Lorenzo Boga
Lorenzo Boga

Reputation: 13

How to separate an array by a property?

I have an array of products that have 5 properties, one of those being "category". What i want to achieve is to get a new array that separates these products by category BUT with the category in a "title" property, so the final array has the shape of

[{
title: "category1",
data: [{product1,product2,...}]
},{
title: "category2",
data: [{product3,product4,...}]}
]

I found a similar question but that doesnt give me the "title" prop, instead it gives me:

[{
cateogry1: [{product1,product2,...}],
category2: [{product3,product4,...}],
}]

And this doesnt work because im trying to use this array in a SectionList in ReactNative which needs the data to have the other specific shape. If anyones know a way in which I can separate the array like this or use the original array in a SectionList that would be great.

Upvotes: 0

Views: 55

Answers (1)

Gianmarco Digiacomo
Gianmarco Digiacomo

Reputation: 312

You can use the reduce() method of the Array to "map" your items one after the other


// You can have as many extra attributes as you want inside here. I only put "index"
const products = [{
    category: 'category1',
    index: '1'
  },
  {
    category: 'category2',
    index: '2'
  },
  {
    category: 'category2',
    index: '3'
  },
  {
    category: 'category1',
    index: '4'
  },
  {
    category: 'category1',
    index: '5'
  },
  {
    category: 'category2',
    index: '6'
  },
]


// Use a reduce on the existing array. It iterate on the array and provide 
// an accumulator (here called acc) initialized at the last row as an empty array
const transformedProducts = products.reduce((acc, product) => {
  // Look for an existing object. Search in the accumulator a title equal to the current iterated product category
  const index = acc.findIndex(group => group.title === product.category)
    
  if(index < 0) {
      // If no existing object is found you create one and put the iterated product in it
      acc.push({ title: product.category, data: [product] })
  } else {
      // If you find it you use it to add the new product to the list
      acc[index].data = [...acc[index].data, product]
  }
    
  return acc
}, []);

Upvotes: 3

Related Questions