Reorganizing an Array of Objects in Javascript: “Uncaught TypeError: Cannot read property 'push' of undefined”

ε祈祈猫儿з 提交于 2021-01-29 09:10:45

问题


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:

  1. Replace your if condition with out[tags_entries[i]['entry_id']]['tags']

  2. 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'] = [];
  1. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!