简体   繁体   中英

How to loop over object with unknown keys and values

I get a JSON response of shoe sizes from an API endpoint that looks like this:

data: [{
    0: {
        system: "US",
        sizes: {
            7: {B: 3, C: 6, D: 1, E: 1}
            7.5: {A: 6, B: 7, C: 14, D: 11, E: 2}
            8: {2E: 1, A: 5, B: 32, C: 38, D: 23, …}
            8.5: {2E: 2, A: 9, B: 56, C: 79, D: 61, …}
            9: {2A: 5, 2E: 4, A: 17, B: 92, C: 143, …}
            9.5: {2A: 3, 2E: 3, A: 26, B: 132, C: 194, …}
            10: {2A: 5, 2E: 3, 3A: 1, A: 53, B: 159, …}
        }
    }
}]

The data shows eg that US size 7 has four different kinds of shapes (B, C, D, E) where 3 people have foots of shape B. In total, 11 people has size 7. The list can contain sizes in US, EU or different systems, and key of shapes can be AZ or basically anything else.

I want to loop over sizes and create a diagram of how many people that has a certain size, and how many has a certain shape of that size.

What would be the best way to loop over an object like this to get the value of every shape? I would expect it to be an array of sizes.

ES6 or ES7 is fine but I would prefer to do it without jQuery.

EDIT: Let me be more clear. First of all I have considered improving data structure but unfortunately that's not an option.

I have tried Object.keys(sizes) which returns an array of the keys. Sure that's one step forward. But I would like to call a function that returns an object with the keys and its values. In my mind, that return value should be something like this:

sizes: [
    {
        size: 7,
        total: 11
        shapes: [
            {name: 'B', value: 3},
            {name: 'C', value: 6},
            {name: 'D', value: 1},
            {name: 'E', value: 1}
        ]
    },{...},{...}
]

Does that makes sense? Of course, length is not absolutely necessary to include in the object.

You can extract all of the keys of an object into an array and simply iterate over that array.

 var obj = { 'key1': 'val1', 'key2': 'val2' } var keys = Object.keys(obj); // ['key1', 'key2'] keys.forEach( function(key) { var values = obj[key] console.log(values) // do stuff with "values" }) 


Reference -

You can use array#map , Object.keys() and array#reduce .

 const data = [{system:'US',sizes:{7:{B:3,C:6,D:1,E:1,}, 7.5: { A: 6, B: 7, C: 14, D: 11, E: 2, }, 8: { '2E': 1, A: 5, B: 32, C: 38, D: 23, }, 8.5: { '2E': 2, A: 9, B: 56, C: 79, D: 61, }, 9: { '2A': 5, '2E': 4, A: 17, B: 92, C: 143, }, 9.5: { '2A': 3, '2E': 3, A: 26, B: 132, C: 194, }, 10: { '2A': 5, '2E': 3, '3A': 1, A: 53, B: 159, }, }, }, ]; var result = data.map((obj) => { return Object.keys(obj.sizes).reduce((arr,k) => { let res = Object.keys(obj.sizes[k]).reduce((r, k1) => { r['size'] = k; r.shapes.push({name: k1, value: obj.sizes[k][k1]}); r.total += obj.sizes[k][k1]; return r; },{shapes:[],total:0}); arr.push(res); return arr; },[]); }) console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Use Object.keys() and .reduce() to sum the values of the keys.

NOTE : I had to clean your data, and remove a level to simplify the example. You'll need to adapt it to your real data.

 const data = [ { system: 'US', sizes: { 7: { B: 3, C: 6, D: 1, E: 1, }, 7.5: { A: 6, B: 7, C: 14, D: 11, E: 2, }, 8: { '2E': 1, A: 5, B: 32, C: 38, D: 23, }, 8.5: { '2E': 2, A: 9, B: 56, C: 79, D: 61, }, 9: { '2A': 5, '2E': 4, A: 17, B: 92, C: 143, }, 9.5: { '2A': 3, '2E': 3, A: 26, B: 132, C: 194, }, 10: { '2A': 5, '2E': 3, '3A': 1, A: 53, B: 159, }, }, }, ]; const { // We use destructuration to make a copy sizes = {} // We assign a default value in case sizes is undefined } = data[0]; const sumOfSizes = {}; // Future object we will fill Object.keys(sizes).forEach((sizeIndex) => { // We get the keys of the object, and loop over it. const size = sizes[sizeIndex]; // For clarity, I assigned the needed value to a var. const sumOfShapes = Object.keys(size).reduce((prevSum, shapeIndex) => { // We get the sub-keys of the object and sum the values of them. const shapeValue = size[shapeIndex]; return prevSum + shapeValue; }, 0); sumOfSizes[sizeIndex] = sumOfShapes; // We assign the sum of shapes to the current shoe size. }); console.log(sumOfSizes); 

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