4

I have the following array a as shown below:

var a = [
  {name: 'phone' , id:1 ,num:1},
  {name: 'milk' ,id:2, num:1},
  {name: 'apple' , id:3 , num:1},
  {name: 'phone', id: 4, num:3},
]

I want to filter by array name and add their own num

var currentName = a[0]
let newArrys=[]
for(let i = 0; i<a.length;i++){
   if(currentName.name == a[i].name){
       a[i].num = a[i].num + currentName.num
       let tmepArry = [];
        tempArry.push(a[i]);
        newArrys.push(tempArry);
   }
}

I am trying to obtain the following 2D array:

[
 [{name: 'phone', id:1, num:4}],
 [{name: 'milk',id:2, num:1}],
 [{name: 'apple', id: 3 num:1}]
]

The result cannot be screened out.

My attempt is invalid.

Can you help me?

1
  • 1
    A little thrown off by the result being a 2d array, but you want to use Array.reduce for this. Commented Aug 6, 2019 at 1:53

3 Answers 3

3

Given:

var a = [
  {name: 'phone' , id:1 ,num:1},
  {name: 'milk' ,id:2, num:1},
  {name: 'apple' , id:3 , num:1},
  {name: 'phone', id: 4, num:3},
]
const newArrys = a.reduce((acc, current) => {
  // find an object in the array with a matching name
  const existing = acc.find(obj => obj.name === current.name);
  if (existing) {
    // combine the numbers
    existing.num += current.num;
  } else {
    acc.push(current);
  }
  return acc;
}, []).map(obj => [obj])

That will get you what you need.

Sign up to request clarification or add additional context in comments.

Comments

1

Here's a quick example of how to go about it. Essentially it's a two step process that involves first reducing your array of objects into a distinct list with the counts (num). Then, iterating over your results to create your 2D array.

There's probably a fancier way to produce the same result by adding a little bit more code to the reducer, but trying to go for readability here as it's rather easy to get lost in reduce functions.

var a = [
  {name: 'phone' , id:1 ,num:1},
  {name: 'milk' ,id:2, num:1},
  {name: 'apple' , id:3 , num:1},
  {name: 'phone', id: 4, num:3},
]

// Get the counts using reduce
const results = a.reduce( (acc, curr) => {
	if (acc.hasOwnProperty(curr.name)) {
  	acc[curr.name].num += curr.num;
  } else {
  	acc[curr.name] = {id: curr.id, num: curr.num };
  }
  return acc;
}, {});

// Establish result array
const finalResult = [];
// Iterate over results object and format them into an array of a single object
// then push the array to the finalResult array (thus making it 2D)
for (const key in results) {
	const item = results[key];
	finalResult.push([{ name: key, id: item.id, num: item.num }]);
}

console.log(finalResult);

1 Comment

Thank you very much for your answer, which is very detailed
0

Not sure if this is the best solution but it does work. Please feel free to give advise on what I should have done instead for a better code. Haha..

var a = [
  {name: 'phone' , id:1 ,num:1},
  {name: 'milk' ,id:2, num:1},
  {name: 'apple' , id:3 , num:1},
  {name: 'phone', id: 4, num:3},
]

function organize_array(tmpArray) {
  let data = []
  tmpArray.forEach(function(value, key) {
      if(data.filter(tmp => tmp.name == value.name) == '') {
        const tmpFiltered = a.filter(tmp => tmp.name == value.name)
        let total = 0
        tmpFiltered.map(x => { total += x.num })
        data.push({name: value.name, num: total})
      }
  })
  return data
}

console.log(organize_array(a))

Comments

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.