0

Given the following scenario, how can I return a single array?

let array = [{
    name: "name01", 
    arr: [
      {name: "inner01"}, 
      {name: "inner02"}, 
      {name: "inner03"}
    ]
  }, {
    name: "name02", 
    arr: [
      {name: "inner04"}, 
      {name: "inner05"}, 
      {name: "inner06"}
    ]
  }
]

let convo = array.map(item => {
  return {
    name: item.name,
    ...item.arr,
  };
});

https://jsfiddle.net/3ng8dc2x/1/

I would like to get something like:

[
  {name: "name01"}, 
  {name: "inner01"}, 
  {name: "inner02"}, 
  {name: "inner03"},
  {name: "name02"},
  {name: "inner04"}, 
  {name: "inner05"}, 
  {name: "inner06"}
]

As always any and all direction is appreciated, so thanks in advance!

studiobrain
  • 1,135
  • 2
  • 13
  • 35

4 Answers4

5

If you are writing for the latest browsers and latest node, flatMap() is perfect for this:

let array = [{
    name: "name01", 
    arr: [
      {name: "inner01"}, 
      {name: "inner02"}, 
      {name: "inner03"}
    ]
  }, {
    name: "name02", 
    arr: [
      {name: "inner04"}, 
      {name: "inner05"}, 
      {name: "inner06"}
    ]
  }
]

let flat = array.flatMap(({name, arr}) => [{name}, ...arr])
console.log(flat)
Mark
  • 90,562
  • 7
  • 108
  • 148
  • 2
    just noticed, the result is missing `name01` and `name02` – Get Off My Lawn Apr 11 '19 at 04:11
  • And you missed adding `name` key's in output `name01` and `name02` – Code Maniac Apr 11 '19 at 04:12
  • @GetOffMyLawn it's a fair warning, but I think it's an overstatement to say MDN doesn't suggest using it. It just isn't supposed everywhere yet, but if it is supported where you need, it works well. – Mark Apr 11 '19 at 04:26
2

Array reduce might be a better option than map.

let array = [{
    name: "name01", 
    arr: [
      {name: "inner01"}, 
      {name: "inner02"}, 
      {name: "inner03"}
    ]
  }, {
    name: "name02", 
    arr: [
      {name: "inner04"}, 
      {name: "inner05"}, 
      {name: "inner06"}
    ]
  }
]

let convo = array.reduce((a, {name, arr}) => a.concat([{name}], arr), []);
console.log(convo)
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
  • 1
    on side note:- And you missed adding `name` keys in output `name01` and `name02` – Code Maniac Apr 11 '19 at 04:12
  • Because of the nature of my use case and the preference for concise code, this will work great! Thanks! ...and thanks for all of the different views and directions to solve for this! – studiobrain Apr 11 '19 at 04:35
1

One possible solution is to combine Array.reduce() with Object.entries and for every entry of the current inspected object, check the type to decide how to put the element on a new array:

let array = [
  {
    name: "name01", 
    surname: "surname01", 
    arr: [{name: "inner01"}, {name: "inner02"}, {name: "inner03"}]
  },
  {
    name: "name02",
    surname: "surname02",  
    arr: [{name: "inner04"}, {name: "inner05"}, {name: "inner06"}]
  }
];

let res = array.reduce((acc, curr) =>
{
    Object.entries(curr).forEach(([k, v]) =>
    {
        if (typeof v === 'string')
            acc.push({[k]: v});
        else if (Array.isArray(v))
            acc.push(...v);
    });

    return acc;
}, []);

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Note, the previous is likely a generic solution, however, if you can trust on the structure of your objects, i.e, they all have a name property holding a string and an array on the property arr, then the code can be simplified:

let array = [
  {
    name: "name01", 
    arr: [{name: "inner01"}, {name: "inner02"}, {name: "inner03"}]
  },
  {
    name: "name02", 
    arr: [{name: "inner04"}, {name: "inner05"}, {name: "inner06"}]
  }
];

let res = array.reduce(
    (acc, {name, arr}) => acc.concat([{name}, ...arr]),
    []
);

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Shidersz
  • 16,846
  • 2
  • 23
  • 48
0

You can use reduce and destructuring assignment

let array = [{name: "name01", arr: [{name: "inner01"}, {name: "inner02"}, {name: "inner03"}]},
{name: "name02", arr: [{name: "inner04"}, {name: "inner05"}, {name: "inner06"}]}]

let op = array.reduce((op,{name,arr}) =>op.concat([{name}],arr),[])

console.log(op)
Code Maniac
  • 37,143
  • 5
  • 39
  • 60