问题
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