Home > Blockchain >  Flatmap() keeping parent and child both JS
Flatmap() keeping parent and child both JS

Time:01-17

I have this array in which some obj's dont have children I want flatten it.

export const Array = [
  {
    id: "1",
    title: "Dashboard 1",
  },
  {
    id: "2",
    title: "Dashboard 2",
  },
  {
    id: "3",
    title: "Dashboard 3",
  },
 {
    id: "10",
    title: "Dashboard 7",
    subNav: [
      {
        id: "11",
        title: "Dashboard 4",
      },
      {
        id: "12",
        title: "Dashboard 5",
      },
    ],
  },
 

My Code :

Array.flatMap(item => item.subNav ? item.subNav?.flatMap(item1 => item1) : item)

output :

[{id: '1', title: 'Dashboard 1'},
{id: '2', title: 'Dashboard 2'},
{id: '3', title: 'Dashboard 3'},
{id: '11', title: 'Dashboard 4'} ,
{id: '12', title: 'Dashboard 5']

What I expected :

[{id: '1', title: 'Dashboard 1'},
{id: '2', title: 'Dashboard 2'},
{id: '3', title: 'Dashboard 3'},
{id: '10', title: 'Dashboard 7'} ,
{id: '11', title: 'Dashboard 4'} ,
{id: '12', title: 'Dashboard 5']

CodePudding user response:

You didn't include the parent in the results

const array = [
  {
    id: "1",
    title: "Dashboard 1",
  },
  {
    id: "2",
    title: "Dashboard 2",
  },
  {
    id: "3",
    title: "Dashboard 3",
  },
  {
    id: "10",
    title: "Dashboard 7",
    subNav: [
      {
        id: "11",
        title: "Dashboard 4",
      },
      {
        id: "12",
        title: "Dashboard 5",
      },
    ],
  },
];

const result = array.flatMap(({ subNav, ...rest }) =>
  [rest, ...(subNav?.flat() || [])]
);

console.log(result);

CodePudding user response:

If navigation is just one level deep, like shown in the example you could use the following:

const result = navs.flatMap(({ subNav = [], ...nav }) => [nav, ...subNav]);

const navs = [
  { id: "1", title: "Dashboard 1" },
  { id: "2", title: "Dashboard 2" },
  { id: "3", title: "Dashboard 3" },
  {
    id: "10",
    title: "Dashboard 7",
    subNav: [
      { id: "11", title: "Dashboard 4" },
      { id: "12", title: "Dashboard 5" },
    ],
  },
];

const result = navs.flatMap(({ subNav = [], ...nav }) => [nav, ...subNav]);
console.log(result);

If there can be more then one level of depth you'll have to use recursion:

function flattenNavs(navs) {
  return navs.flatMap(({ subNav = [], ...nav }) => [nav, ...flattenNavs(subNav)]);
}

const result = flattenNavs(navs);

const navs = [
  { id: "1", title: "Dashboard 1" },
  { id: "2", title: "Dashboard 2" },
  { id: "3", title: "Dashboard 3" },
  {
    id: "10",
    title: "Dashboard 7",
    subNav: [
      { id: "11", title: "Dashboard 4" },
      {
        id: "12",
        title: "Dashboard 5",
        subNav: [
          { id: "13", title: "further nested" },
        ],
      },
    ],
  },
];

function flattenNavs(navs) {
  return navs.flatMap(({ subNav = [], ...nav }) => [nav, ...flattenNavs(subNav)]);
}

const result = flattenNavs(navs);
console.log(result);

Both answers rely on object destructuring to unpack each array element.

The subNav property in each element is stored in the subNav parameter. If it's not present we'll use an empty array as the default value. All other properties are stored in the nav parameter.

After unpacking (aka destructuring) the element we want to return both the nav and its subNav items on the same level. To achieve this we'll return [nav, ...subNav]. This will return an array with nav as the first element, then all subNav elements are appended. See: Spread syntax (...): Spread in array literals - MDN

CodePudding user response:

You can tweak your code to use a second Array#flatMap like so:

const 
    arr = [ { id: "1", title: "Dashboard 1", }, { id: "2", title: "Dashboard 2", }, { id: "3", title: "Dashboard 3", }, { id: "10", title: "Dashboard 7", subNav: [ { id: "11", title: "Dashboard 4", }, { id: "12", title: "Dashboard 5" } ] } ], 
    
    newArr = arr.flatMap(item => item.subNav ? [item].flatMap(({subNav,...rest}) => [rest,...subNav]) : item);

console.log( newArr );

CodePudding user response:

Use flatMap() were you spread (...) the object to 2 parts, the subNav (if existing) and the main object that remains

Then you can return that that, again, with spread syntax on the subNav, with a fallback (subNav || []) should there be no subNav

const Array = [{id: "1", title: "Dashboard 1", }, {id: "2", title: "Dashboard 2", }, {id: "3", title: "Dashboard 3", }, {id: "10", title: "Dashboard 7", subNav: [{id: "11", title: "Dashboard 4", }, {id: "12", title: "Dashboard 5", }, ], }, ]
  
const res = Array.flatMap(({ subNav, ...main }) => [ main, ...(subNav || [] ) ]);
  
console.log(res)

[
  {"id": "1",  "title": "Dashboard 1"}, 
  {"id": "2",  "title": "Dashboard 2"},
  {"id": "3",  "title": "Dashboard 3"},
  {"id": "10", "title": "Dashboard 7"},
  {"id": "11", "title": "Dashboard 4"},
  {"id": "12", "title": "Dashboard 5"}
]
  • Related