简体   繁体   English

我如何从递归$ .each对象中删除元素?

[英]How i can delete elements from object in recursive $.each?

For example, i have this data object: 例如,我有此数据对象:

var data = {
    'some': [
        {'id': 10, 'info': [{'next': 11}, {'next': 0}, {'next': 0},  {'next':  0}]}, 
        {'id': 11, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next':  0}]}, 
        {'id': 12, 'info': [{'next': 0},  {'next': 0}, {'next': 20}, {'next':  0}]}, 
        {'id': 13, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next':  0}]}, 
        {'id': 14, 'info': [{'next': 12}, {'next': 0}, {'next': 0},  {'next':  0}]}, 
        {'id': 15, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next':  0}]}, 
        {'id': 16, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next': 14}]}, 
        {'id': 17, 'info': [{'next': 0},  {'next': 0}, {'next': 13}, {'next':  0}]}, 
        {'id': 18, 'info': [{'next': 15}, {'next': 0}, {'next': 0},  {'next':  0}]}, 
        {'id': 19, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next':  0}]}, 
        {'id': 19, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next': 11}]}, 
        {'id': 20, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next':  0}]}
    ]
};

I want delete all elements with id where contains in next , for example, from data object above, i want get something like this 我想删除id包含在next所有元素,例如,从上面的数据对象中,我想要得到这样的东西

    var data = {
        'some': [
            {'id': 10, 'info': [{'next': 11}, {'next': 0}, {'next': 0},  {'next':  0}]}, 
            {'id': 16, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next': 14}]}, 
            {'id': 17, 'info': [{'next': 0},  {'next': 0}, {'next': 13}, {'next':  0}]}, 
            {'id': 18, 'info': [{'next': 15}, {'next': 0}, {'next': 0},  {'next':  0}]}, 
            {'id': 19, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next':  0}]}, 
            {'id': 19, 'info': [{'next': 0},  {'next': 0}, {'next': 0},  {'next': 11}]}, 
        ]
    };

I write this script, but it return Uncaught TypeError: Cannot read property 'id' of undefined , why? 我编写了此脚本,但返回Uncaught TypeError: Cannot read property 'id' of undefined ,为什么?

var cleanData = function (d var cleanData =函数(d

ata) {
    $.each(data['some'], function (_is, some) {
        $.each(some['info'], function (_in, next) {
            if (next['next']) 
                $.each(data['some'], function (_is2, some2) {
                    if (some2['id'] == next['next']) 
                        data['some'].remove(_is2);
                });
        });
    });

    return data;
};

My example on JsFiddle. 我在JsFiddle上的示例。

Thanks. 谢谢。

UPDATE: See Andrew's answer on this page. 更新: 请参阅本页上安德鲁的答案。 It's a much cleaner and safer solution. 这是一个更干净,更安全的解决方案。

In short, you can't. 简而言之,你不能。 You'll have to use a regular for loop with an index, instead, so that you can keep up with the new length of your array. 您必须使用带有索引的常规for循环,以便可以跟上数组的新长度。

$.each(data['some'], function (_is, some) {
    $.each(some['info'], function (_in, next) {
        if (next['next']) 
            for(var i=0, len=data['some'].length; i < len; i++) {
                var some2 = data['some'][i];
                if (some2['id'] == next['next']) {
                    data['some'].remove(_is2);
                    // Decrement i since the next item will now be in the place of the one you removed.
                    i--;
                    // Decrement len since your array now holds one less item.
                    len--;
                }
            }
        }
    });
});

Array.prototype.filter is great for a problem like this. Array.prototype.filter非常适合解决此类问题。 This code should produce what you're looking for: 此代码应产生您想要的内容:

data.some = data.some.filter(function(item) {
    return item.info.filter(function(i) {
        return i.next > 0;
    }).length > 0;
});

You can create this in two steps: First find all the IDs that are contained in any next object. 您可以分两个步骤创建它:首先找到next对象中包含的所有ID。 Then filter the array and remove the rows with that IDs. 然后过滤数组并删除具有该ID的行。

Example: 例:

// Build ids table
var idsToRemove = data.some.reduce(function(ids, row) {
  return row.info.reduce(function(ids, obj) {
    return ids[obj.next] = true, ids;
  }, ids);
}, {});

// Filter out rows with those IDs
data.some = data.some.filter(function(row) {
  return !idsToRemove[row.id];
});

console.log(data);

 var data = { 'some': [ {'id': 10, 'info': [{'next': 11}, {'next': 0}, {'next': 0}, {'next': 0}]}, {'id': 11, 'info': [{'next': 0}, {'next': 0}, {'next': 0}, {'next': 0}]}, {'id': 12, 'info': [{'next': 0}, {'next': 0}, {'next': 20}, {'next': 0}]}, {'id': 13, 'info': [{'next': 0}, {'next': 0}, {'next': 0}, {'next': 0}]}, {'id': 14, 'info': [{'next': 12}, {'next': 0}, {'next': 0}, {'next': 0}]}, {'id': 15, 'info': [{'next': 0}, {'next': 0}, {'next': 0}, {'next': 0}]}, {'id': 16, 'info': [{'next': 0}, {'next': 0}, {'next': 0}, {'next': 14}]}, {'id': 17, 'info': [{'next': 0}, {'next': 0}, {'next': 13}, {'next': 0}]}, {'id': 18, 'info': [{'next': 15}, {'next': 0}, {'next': 0}, {'next': 0}]}, {'id': 19, 'info': [{'next': 0}, {'next': 0}, {'next': 0}, {'next': 0}]}, {'id': 19, 'info': [{'next': 0}, {'next': 0}, {'next': 0}, {'next': 11}]}, {'id': 20, 'info': [{'next': 0}, {'next': 0}, {'next': 0}, {'next': 0}]} ] }; // Build ids table var ids = data.some.reduce(function(ids, row) { return row.info.reduce(function(ids, obj) { return ids[obj.next] = true, ids; }, ids); }, {}); // Filter out rows with those IDs data.some = data.some.filter(function(row) { return !ids[row.id]; }); console.log(data); 

使用for时长大于零并从数组中删除索引一

The error you're getting is because not every object in the array has a property with a key of 'id' 您得到的错误是因为并非数组中的每个对象都有一个键为'id'的属性。

I'm not exactly clear on what is supposed to be removed, but if it's everything that's first key is 'next, change this: 对于要删除的内容,我还不太清楚,但是如果所有的第一要点都是“下一步”,请更改此内容:

if (some2['id'] == next['next']) 

to this: 对此:

if (some2[0] == 'next') 

Working Demo 工作演示

HTH, HTH,

-Ted -泰德

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM