简体   繁体   中英

How to map from an array of object to a different array of arrays aggregating/flattering by some field?

I've this array of objects:

[
    {
        "n": "David",
        "t": 1,
        "o": "2"
    },
    {
        "n": "Paul",
        "t": 3,
        "o": "4"
    },
    {
        "n": "David",
        "t": 5,
        "o": "6"
    },
    {
        "n": "David",
        "t": 7,
        "o": "8"
    },
    {
        "n": "Paul",
        "t": 9,
        "o": "10"
    }
]

And I need to map to this:

[
    [
        "David",
        [
            [1, "2"],
            [5, "6"],
            [7, "8"]
        ]
    ],
    [
        "Paul",
        [
            [3, "4"],
            [9, "10"]
        ]
    ]
]

So basically an array of array, where each inner array is a "group by" the field "n" field and all elements aggregated become arrays.

To get the output, use object to store the index of the stored mapped array with name. [eg for David, it's 0 and for Paul, it's 1]. We can use string Index in the array for the readable purpose but I don't think that's a great idea as output schema is not that complex.

 const data = [ { "n": "David", "t": 1, "o": "2" }, { "n": "Paul", "t": 3, "o": "4" }, { "n": "David", "t": 5, "o": "6" }, { "n": "David", "t": 7, "o": "8" }, { "n": "Paul", "t": 9, "o": "10" } ]; // to save the index for the name const nameHash = {}; // to save the output const output = []; for (let obj of data) { const {n, t, o} = obj; if (!(n in nameHash)) { nameHash[n] = output.length; output.push([n, []]); } let index = nameHash[n]; output[index][1].push([t, o]); } console.log(output);

you can do it using Array.reduce and Object.entries

 const transform = data => Object.entries(data.reduce((res, {n,t,o}) => { const existing = res[n] || [] return { ...res, [n]: [...existing, [t, o]] } }, {})) const data = [ { "n": "David", "t": 1, "o": "2" }, { "n": "Paul", "t": 3, "o": "4" }, { "n": "David", "t": 5, "o": "6" }, { "n": "David", "t": 7, "o": "8" }, { "n": "Paul", "t": 9, "o": "10" } ] console.log(transform(data))

The usual solution using reduce . Group by the n and the take the values of object using Object.values

 const a = [ { "n": "David", "t": 1, "o": "2" }, { "n": "Paul", "t": 3, "o": "4" }, { "n": "David", "t": 5,"o": "6" }, { "n": "David", "t": 7, "o": "8" },{ "n": "Paul", "t": 9, "o": "10" }] const res = Object.values(a.reduce((acc,{n,t,o}) => { acc[n]??=[n,[]] acc[n][1].push([t,o]) return acc },{})) console.log(res)

or using a for of loop

 const a = [ { "n": "David", "t": 1, "o": "2" }, { "n": "Paul", "t": 3, "o": "4" }, { "n": "David", "t": 5,"o": "6" }, { "n": "David", "t": 7, "o": "8" },{ "n": "Paul", "t": 9, "o": "10" }] const res = {} for(el of a){ const {n,o,t} = el res[n] = res[n] || [n,[]] res[n][1].push([t,o]) } console.log(Object.values(res))

Make a dictionary out of the data and then put the result in the desired format.

 const data=[{n:"David",t:1,o:"2"},{n:"Paul",t:3,o:"4"},{n:"David",t:5,o:"6"},{n:"David",t:7,o:"8"},{n:"Paul",t:9,o:"10"}]; let dict = {}; data.forEach(d => { if (!dict[dn]){ dict[dn] = [[dt, do]]; } else { dict[dn].push([dt, do]); } }); let result = []; Object.entries(dict).forEach(d => { result.push([d[0],d[1]]); }); console.log(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM