Объединить элементы массива по категориям - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть этот массив:

[ [ 'TWENTY', 20 ],
  [ 'TWENTY', 20 ],
  [ 'TWENTY', 20 ],
  [ 'TEN', 10 ],
  [ 'TEN', 10 ],
  [ 'FIVE', 5 ],
  [ 'FIVE', 5 ],
  [ 'FIVE', 5 ],
  [ 'DOLLAR', 1 ],
  [ 'QUARTER', 0.25 ],
  [ 'QUARTER', 0.25 ],
  [ 'DIME', 0.1 ],
  [ 'DIME', 0.1 ],
  [ 'PENNY', 0.01 ],
  [ 'PENNY', 0.01 ],
  [ 'PENNY', 0.01 ],
  [ 'PENNY', 0.01 ] ]

, и я хочу объединить содержимое, чтобы у меня было:

[ [ 'TWENTY', 60 ],
  [ 'TEN', 20 ],
  [ 'FIVE', 15 ],
  [ 'DOLLAR', 1 ],
  [ 'QUARTER', 0.50 ],
  [ 'DIME', 0.2 ],
  [ 'PENNY', 0.04 ]]

Я пытался перебирать массив и суммировать значения, но имел нет успеха Очень ценю вашу помощь. Маттиа П

Ответы [ 7 ]

4 голосов
/ 15 апреля 2020

Вы можете сделать это за один l oop с объектом в качестве карты:

const array = [ [ 'TWENTY', 20 ],
  [ 'TWENTY', 20 ],
  [ 'TWENTY', 20 ],
  [ 'TEN', 10 ],
  [ 'TEN', 10 ],
  [ 'FIVE', 5 ],
  [ 'FIVE', 5 ],
  [ 'FIVE', 5 ],
  [ 'DOLLAR', 1 ],
  [ 'QUARTER', 0.25 ],
  [ 'QUARTER', 0.25 ],
  [ 'DIME', 0.1 ],
  [ 'DIME', 0.1 ],
  [ 'PENNY', 0.01 ],
  [ 'PENNY', 0.01 ],
  [ 'PENNY', 0.01 ],
  [ 'PENNY', 0.01 ] ];
  
const result = array.reduce((map,[key,val]) => {
  map[key] = (map[key] || 0) + val;
  return map;
}, {});

console.log(Object.entries(result));

Object.entries(result) превращает его из приятного объекта, к которому вы можете получить доступ, например, result.PENNY, в нужный формат массива. Возможно, вам будет проще использовать ее в качестве карты, в этом случае просто пропустите Object.entries(...).

3 голосов
/ 15 апреля 2020

Используя .reduce() и .find(), вы можете группировать по первому элементу внутреннего массива.

Попробуйте выполнить следующее:

const array = [ [ 'TWENTY', 20 ],
  [ 'TWENTY', 20 ],
  [ 'TWENTY', 20 ],
  [ 'TEN', 10 ],
  [ 'TEN', 10 ],
  [ 'FIVE', 5 ],
  [ 'FIVE', 5 ],
  [ 'FIVE', 5 ],
  [ 'DOLLAR', 1 ],
  [ 'QUARTER', 0.25 ],
  [ 'QUARTER', 0.25 ],
  [ 'DIME', 0.1 ],
  [ 'DIME', 0.1 ],
  [ 'PENNY', 0.01 ],
  [ 'PENNY', 0.01 ],
  [ 'PENNY', 0.01 ],
  [ 'PENNY', 0.01 ] ];
  
const result = array.reduce((a, c) => {
  const found = a.find(f => f[0] === c[0]);
  
  if (found) found[1] += c[1];
  else a.push(c);

  return a;
}, []);

console.log(result);

Надеюсь, это поможет!

1 голос
/ 15 апреля 2020

Вы можете использовать однострочный подход с Map.

var data = [['TWENTY', 20], ['TWENTY', 20], ['TWENTY', 20], ['TEN', 10], ['TEN', 10], ['FIVE', 5], ['FIVE', 5], ['FIVE', 5], ['DOLLAR', 1], ['QUARTER', 0.25], ['QUARTER', 0.25], ['DIME', 0.1], ['DIME', 0.1], ['PENNY', 0.01], ['PENNY', 0.01], ['PENNY', 0.01], ['PENNY', 0.01]],
    result = Array.from(data.reduce((m, [k, v]) => m.set(k, (m.get(k) || 0) + v), new Map));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 15 апреля 2020

Если вы хотите абстрагировать это до простой функции, она может выглядеть так:

const total = array => Object .entries (array .reduce (
  (acc, [name, val]) => ({...acc, [name]: (acc [name] || 0) + val})
  , {}
))

const array = [ [ 'TWENTY', 20 ], [ 'TWENTY', 20 ], [ 'TWENTY', 20 ], [ 'TEN', 10 ], [ 'TEN', 10 ], [ 'FIVE', 5 ], [ 'FIVE', 5 ], [ 'FIVE', 5 ], [ 'DOLLAR', 1 ], [ 'QUARTER', 0.25 ], [ 'QUARTER', 0.25 ], [ 'DIME', 0.1 ], [ 'DIME', 0.1 ], [ 'PENNY', 0.01 ], [ 'PENNY', 0.01 ], [ 'PENNY', 0.01 ], [ 'PENNY', 0.01 ] ];

console .log (total (array))
.as-console-wrapper {min-height: 100% !important; top: 0}
0 голосов
/ 15 апреля 2020

Это решение только с одной итерацией:

const array = [ [ 'TWENTY', 20 ],
[ 'TWENTY', 20 ],
[ 'TWENTY', 20 ],
[ 'TEN', 10 ],
[ 'TEN', 10 ],
[ 'FIVE', 5 ],
[ 'FIVE', 5 ],
[ 'FIVE', 5 ],
[ 'DOLLAR', 1 ],
[ 'QUARTER', 0.25 ],
[ 'QUARTER', 0.25 ],
[ 'DIME', 0.1 ],
[ 'DIME', 0.1 ],
[ 'PENNY', 0.01 ],
[ 'PENNY', 0.01 ],
[ 'PENNY', 0.01 ],
[ 'PENNY', 0.01 ] ];

let result = {};
array.forEach(item => {
      if(result[item[0]]) {
         result[item[0]][1] +=item[1]
      } else {
         result[item[0]] = item;   
      }
})
console.log(result)
0 голосов
/ 15 апреля 2020

Вы можете сделать это, используя reduce и findIndex.

const data = [[ 'TWENTY', 20 ], [ 'TWENTY', 20 ], [ 'TWENTY', 20 ], [ 'TEN', 10 ], [ 'TEN', 10 ], [ 'FIVE', 5 ], [ 'FIVE', 5 ], [ 'FIVE', 5 ], [ 'DOLLAR', 1 ], [ 'QUARTER', 0.25 ], [ 'QUARTER', 0.25 ], [ 'DIME', 0.1 ], [ 'DIME', 0.1 ], [ 'PENNY', 0.01 ], [ 'PENNY', 0.01 ], [ 'PENNY', 0.01 ], [ 'PENNY', 0.01 ]];

const res = data.reduce((a, [k, v]) => {
	let index = a.findIndex(x => x[0] === k);
	
	if (index === -1) {
		a.push([k, v]);
	} else {
		a[index][1] += v;
	}
	return a;
}, []);

console.log(res);
.as-console-wrapper {
  min-height: 100% !important;
  top: 0;
}
0 голосов
/ 15 апреля 2020
const a = [['TWENTY', 20],
 ['TWENTY', 20],
 ['TWENTY', 20],
 ['TEN', 10],
 ['TEN', 10],
 ['FIVE', 5],
 ['FIVE', 5],
 ['FIVE', 5],
 ['DOLLAR', 1],
 ['QUARTER', 0.25],
 ['QUARTER', 0.25],
 ['DIME', 0.1],
 ['DIME', 0.1],
 ['PENNY', 0.01],
 ['PENNY', 0.01],
 ['PENNY', 0.01],
 ['PENNY', 0.01]];

 const b = {};
 const c = [];

 for (const [name, value] of a) {
  if (!b[name]) {
    b[name] = 0;
  }
  b[name] = b[name] + value
 }
 for (const [key, value] of Object.entries(b)) {
  c.push([key, value])
 }

console.log(c)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...