问题
I have an array of objects, each of which pairs an entry id with a tag id. I'm trying to reorganize this so that I get an object with a single index for each unique entry_id with a corresponding list of the associated tags.
Changing this:
tags_entries = [
{'entry_id': 1, 'tag_id': 1},
{'entry_id': 1, 'tag_id': 2},
{'entry_id': 2, 'tag_id': 1},
{'entry_id': 2, 'tag_id': 3},
{'entry_id': 3, 'tag_id': 1}
]
To This:
entries = {
1:
{
'tags': [1, 2]
},
2:
{
'tags': [1, 3]
},
3:
{
'tags': [1]
}
}
The function I have so far is below, but I'm getting this error with it: Uncaught TypeError: Cannot read property 'push' of undefined, which is coming from the line after the else
function collect_tags(tags_entries) {
out = {};
for (i=0; i<tags_entries.length;i++)
{
out[tags_entries[i]['entry_id']] = {};
if (!out.hasOwnProperty(tags_entries[i]['entry_id']))
{
out[tags_entries[i]['entry_id']]['tags'] = [];
out[tags_entries[i]['entry_id']]['tags'] = tags_entries[i]['tag_id'];
}
else
{
out[tags_entries[i]['entry_id']]['tags'].push(tags_entries[i]['tag_id']);
}
}
return out;
}
Can anyone help me figure out what's causing this? Thanks so much.
回答1:
So on each iteration, you use the line:
out[tags_entries[i]['entry_id']] = {};
Then you ask, does out have a property tags_entries[i]['entry_id'] ?
Of course it does, you just created it, it's an empty object.
Then you access the tags property of this empty object and get undefined. Then you try to call the push method of undefined and get your error.
As an alternative, if you don't need to support old versions of IE, I would suggest a functional style replacing the entire thing with Array.prototype.reduce .
Or if you just want to fix your code, maybe:
Replace your if condition with
out[tags_entries[i]['entry_id']]['tags']Replace this weird double assignmenet to the same address
out[tags_entries[i]['entry_id']]['tags'] = [];out[tags_entries[i]['entry_id']]['tags'] = tags_entries[i]['tag_id'];
with just creating the array
out[tags_entries[i]['entry_id']]['tags'] = [];
- Don't have an else. Always push your value onto the array, even if you had to just create it.
回答2:
This seems to do what you want:
tags_entries = [
{'entry_id': 1, 'tag_id': 1},
{'entry_id': 1, 'tag_id': 2},
{'entry_id': 2, 'tag_id': 1},
{'entry_id': 2, 'tag_id': 3},
{'entry_id': 3, 'tag_id': 1}
]
entries = {}
tags_entries.forEach(function(e) {
(entries[e.entry_id] ||
(entries[e.entry_id] = {tags: []} )).tags.push(e.tag_id);
});
document.write(JSON.stringify(entries));
来源:https://stackoverflow.com/questions/28056487/reorganizing-an-array-of-objects-in-javascript-uncaught-typeerror-cannot-read