1

I have the same issue of this question but my objects have more keys for example:

[{
  id: 1
  name: "abcd",
  value: 123,
  type: "foo"
},
{
  id: 1
  name: "abcd",
  value: 321,
  type: "faa"
},
{
  id: 2
  name: "dcba",
  value: 456,
  type: "baa"
}]

I want to achieve something like this:

[{
  id: 1,
  name: "abcd",
  value: [123, 321],
  type: ["foo", "faa"]
},
{
  id: 2
  name: "dcba",
  value: [456],
  type: ["baa"]
}]

The extra keys have the same value.

customcommander
  • 17,580
  • 5
  • 58
  • 84
  • I think your question title is inaccurate, it's not slightly nested it has duplicate keys so needs objects to be merged – Jon B Oct 09 '19 at 22:57

2 Answers2

2

The idea is to group by the id, then map each group of objects, pick the id and name from the 1st object, extract all value and type from all objects in the group, transpose, and zip to an another object, and merge them.

const { pipe, groupBy, prop, values, map, converge, merge, head, pick, props, transpose, zipObj } = R

const fn = pipe(
  groupBy(prop('id')), // groupBy the id
  values, // convert the object of groups to array of groups
  map(converge(merge, [ // map each group by merging the results of...
    pipe(head, pick(['id', 'name'])), // getting the id and name from the 1st item
    pipe(map(props(['value', 'type'])), transpose, zipObj(['value', 'type'])) // extract the value and type and zipping to an object
  ]))
)

const data = [{
  id: 1,
  name: "abcd",
  value: 123,
  type: "foo"
},
{
  id: 1,
  name: "abcd",
  value: 321,
  type: "faa"
},
{
  id: 2,
  name: "dcba",
  value: 456,
  type: "baa"
}]

const result = fn(data)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

You can grab the distinct id , loop over them and group them using filter and map

let data = [{
    id: 1,
    name: "abcd",
    value: 123,
    type: "foo"
},
    {
        id: 1,
        name: "abcd",
        value: 321,
        type: "faa"
    },
    {
        id: 2,
        name: "dcba",
        value: 456,
        type: "baa"
    }];

//grab unique
let distinct = [...new Set(data.map(a => a.id))];

let grouped = distinct.map(d => {
    let filtered=data.filter(d1 => d1.id === d);
    return {
        id: d,
        name: filtered.map(d2 => d2.name)[0],
        value: [...new Set(filtered.map(d2 => d2.value))],
        type: [...new Set(filtered.map(d2 => d2.type))]
    }
});
console.log(grouped);
sumit
  • 15,003
  • 12
  • 69
  • 110