0

I have an array of object like below

var data = [{monthName: "Jun", name:'web', number: 1, month: 6}, 
{monthName: "Jul", name:'web', number: 2, month: 7},
{monthName: "Aug", name:'web', number: 2, month: 8}, 
{monthName: "Jun", name:'sales', number: 12, month: 6}, 
{monthName: "Jul", name:'sales', number: 2, month: 7}]

I want to group the data based on key "name" and then need to get the number as an array.

Sample output like below

datasets: [{
     name: 'web',
     number: [1, 2, 2],
       },{
    name: 'sales',
    number: [12, 2]
         }]

I am not sure about how to group data and then get a key value as array.

I have grouped the data using below code

result = data.reduce(function (r, a) {
             r[a.name] = r[a.name] || [];
             r[a.name].push(a);
        return r;
    }, Object.create(null));

But not sure about how to get the desired output. Can someone help me ?

4 Answers 4

1

While reducing, also build up the wanted result objects if the key doesn't exist yet:

  const result = [];
  { // Make hash viable to GCing after this operation
    const hash = Object.create(null);
    for(const { name, number } of data) {
       if(!hash[name])
         result.push({ name, numbers: hash[name] = [] });
       hash[name].push(number);
    }
  }
Sign up to request clarification or add additional context in comments.

4 Comments

is there any way to get the iteration number also in this example ?I mean here we have two objects in the array so the first object's iteration number will be 1 and second one's will be 2 like that ?
hi the given solution is counting in each steps, i mean for the first item it is coming as 0 as index and for the next item its 3 because the inner loop for creating the number [] also counts here
Ah, at the end do result.forEach((entry, index) => Object.assign(entry, { index })), but its unclear why you need that, I mean you can easily get the index with .indexOf
no problem i have just used result.length inside, solved the issue . thanks for the wonderful solution
1

you'll need to check if the array has an object with the name , if it does, append the number to it, otherwise push a new object :

var data = [
  { monthName: "Jun", name: "web", number: 1, month: 6 },
  { monthName: "Jul", name: "web", number: 2, month: 7 },
  { monthName: "Aug", name: "web", number: 2, month: 8 },
  { monthName: "Jun", name: "sales", number: 12, month: 6 },
  { monthName: "Jul", name: "sales", number: 2, month: 7 }
];

var result = data.reduce((acc, curr) => {
  const ndx = acc.findIndex(e => e.name === curr.name);

  if (ndx > -1) {
    acc[ndx].number.push(curr.number);
  } else {
    acc.push({
      name: curr.name,
      number: [curr.number]
    });
  }

  return acc;
}, []);

console.log(result);

Comments

1

Create a map which groups the entries with reduce, then get the entries of the map with Object.entries and iterate over them with map, creating a new object for each in the process.

var data = [{monthName:"Jun",name:"web",number:1,month:6},{monthName:"Jul",name:"web",number:2,month:7},{monthName:"Aug",name:"web",number:2,month:8},{monthName:"Jun",name:"sales",number:12,month:6},{monthName:"Jul",name:"sales",number:2,month:7}];

function mergeName(arr) {
  let map = data.reduce((a,c) => (a[c.name] = ({...c, 
            number: a[c.name] && a[c.name].number
                    ? a[c.name].number.push(c.number) && a[c.name].number 
                    : [c.number]}),a),{});
  return Object.entries(map).map(o => ({name: o[0], number: o[1].number}))
}

console.log(mergeName(data))

Comments

1

You're answer is almost correct, just add an additional line to push to a number array:

var data = [{monthName: "Jun", name: 'web', number: 1, month: 6},
	{monthName: "Jul", name: 'web', number: 2, month: 7},
	{monthName: "Aug", name: 'web', number: 2, month: 8},
	{monthName: "Jun", name: 'sales', number: 12, month: 6},
	{monthName: "Jul", name: 'sales', number: 2, month: 7}];

result = Object.values(data.reduce(function (r, {name, number}) {
	r[name] = r[name] || {name, number: []};
	r[name].number.push(number);
	return r;
}, {})).map((v, i) => ({...v, iteration: i + 1}));

console.log(result);

1 Comment

is there any way to get the iteration number also in this example ?I mean here we have two objects in the array so the first object's iteration number will be 1 and second one's will be 2 like that ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.