-1

The array data is mixed I want duplicate date and concatenate number in arrays

var data = [
    ['mars 21 21:37', 624],
    ['mars 21 21:37', 599],
    ['mars 21 21:37', 636],
    ['mars 21 21:37', 619],
    ['mars 21 21:37', 625],
    ['mars 21 21:37', 645],
    ['mars 21 21:37', 638],
    ['mars 21 23:24', 733],
    ['mars 21 23:24', 800],
    ['mars 21 23:24', 609],
    ['mars 21 23:24', 615],
    ['mars 22 09:20', 550],
    ['mars 22 09:20', 608],
    ['mars 22 09:20', 609]
];

I am looking for a solution to transform into that

var data = [{
    'mars 21 21:37': [624, 599, 636, 619, 625, 645, 638],
    'mars 21 23:24': [733, 800, 609, 615],
    'mars 22 09:20': [550, 608, 609]
}];

any idea ?

Sibeesh Venu
  • 18,755
  • 12
  • 103
  • 140
HitAngry
  • 53
  • 2
  • It's for objects but the "how to" is the same: [What is the most efficient method to groupby on a JavaScript array of objects?](https://stackoverflow.com/questions/14446511/what-is-the-most-efficient-method-to-groupby-on-a-javascript-array-of-objects) – Andreas Mar 26 '18 at 15:12
  • Why an array with one object? – Ele Mar 26 '18 at 15:13
  • why underscore? – Nina Scholz Mar 26 '18 at 15:40

5 Answers5

1

You could do something like this:

var data = [
  [ 'mars 21 21:37', 624 ],
  [ 'mars 21 21:37', 599 ],
  [ 'mars 21 21:37', 636 ],
  [ 'mars 21 21:37', 619 ],
  [ 'mars 21 21:37', 625 ],
  [ 'mars 21 21:37', 645 ],
  [ 'mars 21 21:37', 638 ],
  [ 'mars 21 23:24', 733 ],
  [ 'mars 21 23:24', 800 ],
  [ 'mars 21 23:24', 609 ],
  [ 'mars 21 23:24', 615 ],
  [ 'mars 22 09:20', 550 ],
  [ 'mars 22 09:20', 608 ],
  [ 'mars 22 09:20', 609 ]
];

let output = {};
data.forEach(([key, value]) => {
    if (Array.isArray(output[key])) {
        output[key].push(value);
    } else {
        output[key] = [value];
    }
})

console.log(output);

If you're after a reduce, you could do something like this:

var data = [
  ['mars 21 21:37', 624],
  ['mars 21 21:37', 599],
  ['mars 21 21:37', 636],
  ['mars 21 21:37', 619],
  ['mars 21 21:37', 625],
  ['mars 21 21:37', 645],
  ['mars 21 21:37', 638],
  ['mars 21 23:24', 733],
  ['mars 21 23:24', 800],
  ['mars 21 23:24', 609],
  ['mars 21 23:24', 615],
  ['mars 22 09:20', 550],
  ['mars 22 09:20', 608],
  ['mars 22 09:20', 609]
];

data = data.reduce((carry, [key, value]) => {
  if (Array.isArray(carry[key])) {
    carry[key].push(value)
  } else {
    carry[key] = [value]
  }
  return carry;
}, {});

console.log(data)

// If you're after the super compressed version you could do this:
// data = data.reduce((c,[k,v])=>(c[k]=[...(c[k]||[]),v],c),{});
scagood
  • 784
  • 4
  • 11
1

You can use Array.prototype.reduce() combined with Array.prototype.concat():

const data = [['mars 21 21:37', 624],['mars 21 21:37', 599],['mars 21 21:37', 636],['mars 21 21:37', 619],['mars 21 21:37', 625],['mars 21 21:37', 645],['mars 21 21:37', 638],['mars 21 23:24', 733],['mars 21 23:24', 800],['mars 21 23:24', 609],['mars 21 23:24', 615],['mars 22 09:20', 550],['mars 22 09:20', 608],['mars 22 09:20', 609]];
const result = data.reduce((a, [d, v]) => (a[d] = a[d] ? a[d].concat(v) : [v], a), {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Yosvel Quintero
  • 18,669
  • 5
  • 37
  • 46
0

You can use reduce method and return an object as a result.

var data = [ [ 'mars 21 21:37', 624 ],[ 'mars 21 21:37', 599 ],[ 'mars 21 21:37', 636 ],[ 'mars 21 21:37', 619 ],[ 'mars 21 21:37', 625 ],[ 'mars 21 21:37', 645 ],[ 'mars 21 21:37', 638 ],[ 'mars 21 23:24', 733 ],[ 'mars 21 23:24', 800 ],[ 'mars 21 23:24', 609 ],[ 'mars 21 23:24', 615 ],[ 'mars 22 09:20', 550 ],[ 'mars 22 09:20', 608 ],[ 'mars 22 09:20', 609]];
  
const result = data.reduce((r, [time, value]) => {
  if(!r[time]) r[time] = [value]
  else r[time].push(value);
  return r;
}, {})

console.log(result)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
0

You can use the function reduce to build the desired output.

var data = [ [ 'mars 21 21:37', 624 ],  [ 'mars 21 21:37', 599 ],  [ 'mars 21 21:37', 636 ],  [ 'mars 21 21:37', 619 ],  [ 'mars 21 21:37', 625 ],  [ 'mars 21 21:37', 645 ],  [ 'mars 21 21:37', 638 ],  [ 'mars 21 23:24', 733 ],  [ 'mars 21 23:24', 800 ],  [ 'mars 21 23:24', 609 ],  [ 'mars 21 23:24', 615 ],  [ 'mars 22 09:20', 550 ],  [ 'mars 22 09:20', 608 ],  [ 'mars 22 09:20', 609 ] ],
    result = data.reduce((a, [date, value]) => ((a[date] || (a[date] = [])).push(value), a), {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ele
  • 33,468
  • 7
  • 37
  • 75
0

You could use a chain approach with underscore.js by grouping first and then simplify the collected values.

var data = [['mars 21 21:37', 624], ['mars 21 21:37', 599], ['mars 21 21:37', 636], ['mars 21 21:37', 619], ['mars 21 21:37', 625], ['mars 21 21:37', 645], ['mars 21 21:37', 638], ['mars 21 23:24', 733], ['mars 21 23:24', 800], ['mars 21 23:24', 609], ['mars 21 23:24', 615], ['mars 22 09:20', 550], ['mars 22 09:20', 608], ['mars 22 09:20', 609]];
  
console.log(_
    .chain(data)
    .groupBy(([date]) => date)
    .mapObject(values => values.map(([, v]) => v))
    .value()
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392