0

I'm sure this has been answered many times, but I guess I either don't know how to ask the question, or I'm not understanding how to apply concepts from simple array reduce/flatten situations into slightly more complex object arrays.

Say I have an array of objects 'Item' that has 2 properties, 'Name' and 'SubItems,' which is itself an array of objects with a 'Name' property.

Conceptually, something like this...

[
  { Name: 'Obj1', SubItems: [{Name: 'Sub1'}, {Name: 'Sub2'}, {Name: 'Sub'3}] }, 
  { Name: 'Obj2', SubItems: [{Name: 'Sub4'}, {Name: 'Sub5'}] }
]

What's a good way to "flatten" or "select many" of the SubItems, preferably just using javascript? Essentially, I want a single array of SubItems:

[
{Name: 'Sub1'},
{Name: 'Sub2'},
{Name: 'Sub3'},
{Name: 'Sub4'},
{Name: 'Sub5'}
]
Josh
  • 1,876
  • 3
  • 21
  • 35

2 Answers2

2

Sounds like you just need to extract the SubItems property. You can achieve this consisely by spreading into [].concat:

const input = [
  { Name: 'Obj1', SubItems: [{Name: 'Sub1'}, {Name: 'Sub2'}, {Name: 'Sub3'}] }, 
  { Name: 'Obj2', SubItems: [{Name: 'Sub4'}, {Name: 'Sub5'}] }
];

console.log(
  [].concat(...input.map(({ SubItems }) => SubItems))
);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
2

Use the reduce function with [] as initial value, as proposed in this answer:

var foo = [
  { Name: 'Obj1', SubItems: [{Name: 'Sub1'}, {Name: 'Sub2'}, {Name: 'Sub3'}] }, 
  { Name: 'Obj2', SubItems: [{Name: 'Sub4'}, {Name: 'Sub5'}] }
];
var bar = foo.reduce((a, b) => a.concat(b.SubItems), []);
Sebastian S
  • 4,420
  • 4
  • 34
  • 63
  • I think these are all right answers and I could have made any of them work in my exact scenario, but this answer got me to my solution the fastest. The combination of reduce and concat got rid of empty sets, combined what I needed, and was exactly what I was looking for. – Josh Jun 13 '18 at 11:45