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

My array consists of arrays that are the same. How do I combine the ones that are the same?

Ozubergs
  • 145
  • 1
  • 2
  • 9
  • 3
    what is the output you expect? – ashish singh Sep 26 '18 at 19:08
  • [ [ 'PENNY', 1.01 ], [ 'NICKEL', 2.05 ], [ 'DIME', 3.1 ], [ 'QUARTER', 4.25 ], [ 'ONE', 90 ], [ 'FIVE', 55 ], [ 'TEN', 20 ], [ 'TWENTY', 60 ], [ 'ONE HUNDRED', 100 ] ] I want the output to look something like this. – Ozubergs Sep 26 '18 at 19:09
  • 5
    @Ozubergs your output makes no sense with the above values. – Daniel A. White Sep 26 '18 at 19:10
  • 2
    Do you mean "see what the total value of each currency type is?" Meaning, at the end, you'd know that the total amount of pennies you have, the total amount of nickels, dimes, etc.? – romellem Sep 26 '18 at 19:11
  • See https://stackoverflow.com/questions/14446511/what-is-the-most-efficient-method-to-groupby-on-a-javascript-array-of-objects – Tainha Sep 26 '18 at 19:12

5 Answers5

2

You can use reduce to sum totals for unique index 0 in the input array:

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

const result = Object.entries(data.reduce((a, e) => {
  a[e[0]] = e[1] + (a[e[0]] || 0);
  return a;
}, {}));

console.log(result);
ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • This doesn't appear to answer the OP's question. They were looking for an array in the format of what they had originally posted. – zfrisch Sep 26 '18 at 19:24
  • You're right. Requirements seemed unclear at the time. All that needs to change is `Object.values()` -> `Object.entries()`. – ggorlen Sep 26 '18 at 21:19
2

there you go

var a = [
  ["TWENTY", 20],
  ["TWENTY", 20],
  ["TWENTY", 20],
  ["TWENTY", 20],
  ["TEN", 10],
  ["FIVE", 5],
  ["ONE", 1],
  ["QUARTER", 0.25],
  ["QUARTER", 0.25],
  ["DIME", 0.1],
  ["DIME", 0.1],
  ["PENNY", 0.01],
  ["PENNY", 0.01],
  ["PENNY", 0.01]
];
var b = a.reduce((acc, curr) => {
  if (acc[curr[0]]) acc[curr[0]] += curr[1];
  else acc[curr[0]] = curr[1];
  return acc;
}, {});

console.log(b);
ashish singh
  • 6,526
  • 2
  • 15
  • 35
2

Array reduce is what you would want to use to total your amounts while keeping them as key/value arrays although I might personally map them as { key: value } and then reduce for a simpler end result.

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

const totals = group.reduce((accumulator, [key, value]) => {
  const index = accumulator.findIndex(([k,v]) => k === key);
  if (index === -1) {
    return [ ...accumulator, [key, value] ];
  }
  const newTotal = [ key, ( accumulator[index][1] + value ) ];
  return [ ...accumulator.slice(0,index), newTotal, ...accumulator.slice(index + 1) ];
},[]);

const totalsAsObject = group.reduce((accumulator, [key, value]) => {
    const objectKeys = Object.keys(accumulator);
    if (objectKeys.includes(key)) {
      return { ...accumulator, [key]: accumulator[key] + value }
    }
    return { ...accumulator, [key]: value }
  },
  {}
);

console.log(totals);
console.log(totalsAsObject);
D Lowther
  • 1,609
  • 1
  • 9
  • 16
1

You can wrap a reduce function with a map accumulator and transform the result back into an array using Array.from

  result = Array.from(arr.reduce((a, cv) => {
    return ([t, amt] = cv,
      (a.has(t)) ? a.set(t, a.get(t) + amt) : a.set(t, amt), a)
  }, new Map()));

let arr = [
    ['TWENTY', 20],
    ['TWENTY', 20],
    ['TWENTY', 20],
    ['TWENTY', 20],
    ['TEN', 10],
    ['FIVE', 5],
    ['ONE', 1],
    ['QUARTER', 0.25],
    ['QUARTER', 0.25],
    ['DIME', 0.1],
    ['DIME', 0.1],
    ['PENNY', 0.01],
    ['PENNY', 0.01],
    ['PENNY', 0.01]
  ],

  result = Array.from(arr.reduce((a, cv) => {
    return ([t, amt] = cv,
      (a.has(t)) ? a.set(t, a.get(t) + amt) : a.set(t, amt), a)
  }, new Map()));

console.log(result);
zfrisch
  • 8,474
  • 1
  • 22
  • 34
0

ES6 alternative :

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

const result = data.reduce((o, [k, v]) => (o[k] = v + o[k] || v, o), {})

console.log( result )
console.log( Object.entries(result) )
Slai
  • 22,144
  • 5
  • 45
  • 53