Generate a new array from another with reduce javascript

Asked

Viewed 218 times

-1

I have the following array:

const array = [
  { a: 1, b: 2 },
  { a: 1, b: 1 },
  { a: 3, b: 4 }
];

I would like a second array to be generated for each time I repeat the attribute to, generates a new element where the to retains its value, and the b add with the b of the second index of the array, resulting in this array below:

[
  { a: 1, b: 3 },
  { a: 3, b: 4 }
];

For that, I used the reduce of javascript, as follows:

const array = [
  { a: 1, b: 2 },
  { a: 1, b: 1 },
  { a: 3, b: 4 }
];

const result = [];

array.reduce((acc, cur)=>{
  let response = {};
  if(acc.a === cur.a){
    response.a = cur.a;
    response.b = acc.b + cur.b;
  }else{
    response = cur;

  }
  result.push(response);
  return cur;
},0);

console.log(result)

As a result:

[ { a: 1, b: 2 }, { a: 2, b: 3 }, { a: 3, b: 4 } ]

How do I make my result :

[ { a: 2, b: 3 }, { a: 3, b: 4 } ]

Using Javascript and reduce;

OBS: the array shown in the above example is only an example, the original is quite extensive and also dynamic. Therefore, I used reduce to access the past and past items of each index of that array.

  • But what is the intended result? It is [ { a: 1, b: 3 }, { a: 3, b: 4 } ] or [ { a: 2, b: 3 }, { a: 3, b: 4 } ] ?

2 answers

1


No need to use the method reduce() to get what you want. Actually it is not the most suitable method to generate a set of objects, in its documentation reduce() is defined like this:

The method reduce() performs a reducing function, provided by you, for each element of the array, resulting in a single return value.

In other words, you are deviating from the purpose of using the method reduce() because you are not trying to reduce the elements of the input to a single object but to several.

Unless it is a challenge to see that it makes the biggest gambiarra to add a certain field of several objects having as reference another field of these objects, it is enough to just iterate through the array with forEach(), or use a simple for as you remembered Hkotsubo, and add up the respective values of b with values already stored in a result array where the index is a. Follow the example commented:

//Array de testes
let arr =[
  { a: 1, b: 2 },
  { a: 1, b: 5 },
  { a: 1, b: 1 },
  { a: 1, b: 1 },
  { a: 11, b: 11 },
  { a: 3, b: 4 },
  { a: 3, b: 4 },
  { a: 3, b: 4 },
  { a: 3, b: 4 }, 
  { a: 3, b: 4 }, 
  { a: 3, b: 41 },
  { a: 13, b: 41 }
];

//Array que receberá o resultado
let result = [];

//Para todos os elementos de arr
arr.forEach(item =>{
  //Se result não tiver o índice item.a definido inicializa result[item.a]
  if (result[item.a] == undefined) result[item.a] = {"a":item.a, "b":0};
  //Soma item.b ao seu respectivo elemento em result
  result[item.a].b += item.b;
});
//Remove os indices não utilizados de result
result = result.filter(item => !!item);
console.log(result);

  • 1

    Perfect! The other answers are using reduce to traverse the array, which is a crooked use of it, since a forEach (or a for simple) would suffice. + 1

-1

I got it this way.

Sample array :

[
  { a: 1, b: 2 },
  { a: 1, b: 5 },
  { a: 1, b: 1 },
  { a: 1, b: 1 },
  { a: 11, b: 11 },
  { a: 3, b: 4 },
  { a: 3, b: 4 },
  { a: 3, b: 4 },
  { a: 3, b: 4 }, 
  { a: 3, b: 4 }, 
  { a: 3, b: 41 },
  { a: 13, b: 41 },
];

Expected array as result:

[
  { a: 1, b: 9 },
  { a: 11, b: 11 },
  { a: 3, b: 61 },
  { a: 13, b: 41 }
];

   const array = [
  { a: 1, b: 2 },
  { a: 1, b: 5 },
  { a: 1, b: 1 },
  { a: 1, b: 1 },
  { a: 11, b: 11 },
  { a: 3, b: 4 },
  { a: 3, b: 4 },
  { a: 3, b: 4 },
  { a: 3, b: 4 }, 
  { a: 3, b: 4 }, 
  { a: 3, b: 41 },
  { a: 13, b: 41 },
];


const result = [];
const allIndex = [];

array.reduce((acc, cur,index)=>{
  //Verifico se o indice atual é igual ao anterior
  if(cur.a === acc.a ){
const response = {};
response.a = cur.a;
response.b = acc.b + cur.b; 
//Caso sim, o atributo b recebe a soma dos valores b passado.
result.push(response)
return response;
  }else{
//caso não, eu verifico se o indice atual é menor que o tamanho atual do novo array sendo criado
if(index < array.length) allIndex.push(result.length - 1);
result.push(cur)
return cur;
  }
  
});



allIndex.push(result.length - 1);

console.log('RESULTADO');
result.map((element,index) => {
  if(allIndex.includes(index)){
console.log(element);
  }
})

Having then console.log showing all the elements of the new array, so I can add in a new array for future use.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.