最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to loop over object with unknown keys and values - Stack Overflow

programmeradmin4浏览0评论

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 e.g 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 A-Z 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.

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 e.g 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 A-Z 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.

Share Improve this question edited Nov 15, 2017 at 16:48 Calsal asked Nov 15, 2017 at 16:00 CalsalCalsal 1,48518 silver badges27 bronze badges 4
  • Well, you already have the data for how many people have a certain shape in size x, because that's the data you've provided. – Andy Commented Nov 15, 2017 at 16:03
  • How would you do this with jQuery? – evolutionxbox Commented Nov 15, 2017 at 16:07
  • FWIW, the data you've added to the question has errors. – Andy Commented Nov 15, 2017 at 16:08
  • An array of objects with nested objects... Consider improving your data structure. – kind user Commented Nov 15, 2017 at 16:08
Add a ment  | 

3 Answers 3

Reset to default 7

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 -

  • Object.keys()

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);

发布评论

评论列表(0)

  1. 暂无评论