0

Hello guys can you help me reduce arrays please. I have two arrays and I need group one of them by mid. Here you can find example

I have array of objects

const arr = [{
    mid: 888,
    name: "test"
  },
  {
    mid: 888,
    name: "test1"
  },
  {
    mid: 888,
    name: "test2"
  },
  {
    mid: 777,
    name: "test10"
  },
]

But I need group by mid and get something like this

const arr = [{
    mid: 888,
    projects: [{
        name: "test"
      },
      {
        name: "test1"
      },
      {
        name: "test2"
      },
    ]
  },
  {
    mid: 777,
    projects: [{
      name: "test10"
    }, ]
  }
]
Bahador Raghibizadeh
  • 1,155
  • 11
  • 23

4 Answers4

1

const arr = [{
    mid: 888,
    name: "test"
  },
  {
    mid: 888,
    name: "test1"
  },
  {
    mid: 888,
    name: "test2"
  },
  {
    mid: 777,
    name: "test10"
  }
];

let newArray = []
arr.map(item => item.mid).filter((value, index, self)=> { 
    return self.indexOf(value) === index;
}).forEach((mid)=>{
    newArray.push({
        mid,
        projects: arr.filter(item => item.mid == mid).map(item =>{ return {name: item.name}; })
    })
})

console.log(newArray)

other way with reduce:

const arr = [{
    mid: 888,
    name: "test"
  },
  {
    mid: 888,
    name: "test1"
  },
  {
    mid: 888,
    name: "test2"
  },
  {
    mid: 777,
    name: "test10"
  }
];

newArray = arr.map(item => item.mid).filter((value, index, self)=> { 
    return self.indexOf(value) === index;
}).map(item=> { return {mid: item, projects: []}})

newArray = arr.reduce((res, current)=>{
    let index = newArray.map(item => item.mid).indexOf(current.mid);
    res[index].projects.push({name: current.name})
    
    return res;
}, newArray)

console.log(newArray)
Bahador Raghibizadeh
  • 1,155
  • 11
  • 23
0

This would be not the fastest way, but may help to better understand the reduce function, by experimenting with snippet) * JsFiddle

let arr = [{
    mid: 888,
    name: 'test'
  },
  {
    mid: 888,
    name: 'test1'
  },
  {
    mid: 888,
    name: 'test2'
  },
  {
    mid: 777,
    name: 'test10'
  },
]

let reduced = arr.reduce((prev, now) => {
  // first iteration, prev == []
  // now == { mid: 888, name: 'test' }
  let index = prev.map(e => e.mid).indexOf(now.mid);
  if (~index) { // if index found
    prev[index].projects.push({
      name: now.name
    })
  } else {
    prev.push({
      mid: now.mid,
      projects: [{
        name: now.name
      }]
    })
  }
  return prev;
}, []); /* Starting from empty array */

console.log( reduced );
OPTIMUS PRIME
  • 1,297
  • 9
  • 20
0

You can group it like this.

var groupedData = _.mapValues(_.groupBy(arr, 'mid'),
                      clist => clist.map(car => _.omit(car, 'mid')));

and result will be

{888: [{
    name: test
  },
  {
    name: test1
  },
  {
    name: test2
  },
],
777: [{
  name: test10
} ]}
Asad Gulzar
  • 403
  • 4
  • 8
0

Here is how just a reduce function can do the trick using filter and ternary case:

const arr = [{mid: 888,name: "test"},
  {mid: 888,name: "test1"},
  {mid: 888, name: "test2"},
  {mid: 777, name: "test10"}];

let newArray = arr.reduce(function (r, row) {
    let dt = r.filter(x => x.mid == row.mid);
    dt.length ? dt[0].projects.push(row.name): r.push({mid: row.mid, projects: [row.name]});
    return r;
}, []);

console.log(newArray);
Bilal Siddiqui
  • 3,579
  • 1
  • 13
  • 20