Search code examples
javascriptmap-function

How to map `Object.values()` over an array of objects nesting objects?


I'm trying to map Object.values() to extract just the values from an array of objects:

const countries = [
    {
        "austria": { value: 1},
        "canada": {value: 2},
        "nepal": { value: 3},
        "india": { value: 4}
    },
    {
        "australia": { value: 10},
        "france": { value: 20},
        "egypt": { value: 40},
        "usa": { value: 20}
    },
    {
        "mexico": { value: 3},
        "germany": { value: 100},
        "southAfrica": { value: 1},
        "china": { value: 10}
    }
]

To get:

// expected output
[
    {
        "austria": [ 1 ],
        "canada": [ 2 ],
        "nepal": [ 3 ],
        "india": [ 4 ]
    },
    {
        "australia": [ 10 ] ,
        "france": [ 20 ],
        "egypt": [ 40 ],
        "usa": [ 20 ]
    },
    {
        "mexico": [ 3 ],
        "germany": [ 100 ],
        "southAfrica": [ 1 ],
        "china": [ 10 ]
    }
]

I tried

Object.values(countries) // returns the same as `countries`

and also tried mapping using ramda's map() to map Object.values() over countries

const R = require("ramda")

R.map(Object.values, countries)
// gives:
// [
//   [ { value: 1 }, { value: 2 }, { value: 3 }, { value: 4 } ],
//   [ { value: 10 }, { value: 20 }, { value: 40 }, { value: 20 } ],
//   [ { value: 3 }, { value: 100 }, { value: 1 }, { value: 10 } ]
// ]

But I don't want to lose the countries names! How can I utilize either vanilla map or ramda's version to get the expected output?


Solution

  • Using Ramda, you have to use use R.map twice:

    1. To map over the items in the array.
    2. To map over each value of the object.

    const countries = [
        {
            "austria": { value: 1},
            "canada": {value: 2},
            "nepal": { value: 3},
            "india": { value: 4}
        },
        {
            "australia": { value: 10},
            "france": { value: 20},
            "egypt": { value: 40},
            "usa": { value: 20}
        },
        {
            "mexico": { value: 3},
            "germany": { value: 100},
            "southAfrica": { value: 1},
            "china": { value: 10}
        }
    ]
    
    const result = R.map(R.map(Object.values))(countries);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>