0

对于以下内容:

var arr = [{ "packageId": "11", "machineId": "1", "operationType": "Download" }, { "packageId": "12", "machineId": "1", "operationType": "Download" }, { "packageId": "14", "machineId": "1", "operationType": "Download" }];
var index = arr.indexOf({ "packageId": "12", "machineId": "1", "operationType": "Download" });
console.log("index: " + index);
arr.splice(index, 1);

我总是得到-1结果。这是为什么?

我需要能够从数组中删除一个对象。

4

3 回答 3

2

[请注意您问题的原始措辞:实际上您的问题中没有 JSON;JSON 指的是对象表示法。您在数组中拥有的和您的indexOf()调用是对象文字,由{}内部的可选属性表示。]

比较对象

问题是您在调用中创建的对象文字indexOf()本身就是一个新对象,因此不等于数组中的任何内容arr。相反,您必须遍历每个对象中的所有属性并检查它们的等价性。我现在快速编写了此函数,您可以在此答案底部的 JSFiddle 链接中对其进行测试。

function compareObjs(obj1, obj2) {
    var k,
        rtn = true; // assume objects are similar, and then attempts to falsify
    for (k in obj1) {
        if (obj1.hasOwnProperty(k) && obj2.hasOwnProperty(k)) { // check property belongs to both obj1 and obj2
            if (typeof obj1[k] === 'Object') {
                compareObjs(obj1, obj2); // recursive call, to compare two objects within the object
            } else {
                rtn = (obj1[k] === obj2[k]) ? rtn : false; // check value of property is equivalent; if not set the return value to false
            }
        } else {
            rtn = false;
        }
    }
}

你给它两个对象,所以在你的问题中,这将是:

compareObjs(arr[1], { "packageId": "12", "machineId": "1", "operationType": "Download" });

这应该返回 true。如果这两个对象不等价,那么它将返回 false。

查找数组元素

我猜你会想用它来检查数组中特定包的位置,在这种情况下,你可能需要遍历你的数组,检查其中的每个对象是否相等,如下所示:

var i = 0, // Declare the variables upfront
    l = arr.length, // including the length of the array
    r = -1;  // and where you want your result, which will automatically be -1 until a match is found.
for (i; i < l; i += 1) {
    r = (compareObjs(arr[i], { "packageId": "12", "machineId": "1", "operationType": "Download" }) && r === -1) ? i : r;
}

这里r应该为您提供找到等效对象的第一个位置。

删除相关数组元素

r然后,您可以使用以下splice()方法从数组中删除引用 的对象:

arr.splice(r, 1);

你可能也想把这段代码放到一个函数中,但我不知道你程序其余部分的结构,所以让你去思考!

JSFiddle 在这里(您需要打开浏览器控制台才能查看结果。)

于 2013-02-28T16:00:54.323 回答
1

您正在创建的{}对象文字实际上是与 中的对象不同的对象arr,因此它们无法直接比较并且indexOf会失败。您必须使用良好的老式迭代:

arr.filter(function (elem) {
    return elem.packageId != 12
        || elem.machineId != 1
        || elem.operationType != 'Download';
});

如果需要,您当然也可以与对象进行比较。

var compareTo = {'packageId': '12'};
arr.filter(function (elem) {
    var matches = 0, elements = 0;
    for (var x in compareTo) {
        elements++;
        if (compareTo.hasOwnProperty(x) && elem.hasOwnProperty(x)
            && elem (x) == compareTo(x)
        ) {
            matches++;
        }
    }
    return matches == elements;
});
于 2013-02-28T15:12:06.103 回答
1

我建议你另一种可能的解决方案。

如果您可以修改数据结构,请使用 Object 来存储数据,将其形状作为关联数组:

var assocArr = new Object();
assocArr["11"] = {"packageId": "11", "machineId": "1", "operationType": "Download"};
assocArr["12"] = { "packageId": "12", "machineId": "1", "operationType": "Download" };
assocArr["14"] = { "packageId": "14", "machineId": "1", "operationType": "Download" };

delete assocArr["11"];

优点:

  • 直接数据访问
  • 简单的插入和删除

您还可以安排一个课程来管理您的数据:

var AssocArray = function(){
  var collection = new Object();

  this.add = function(id, o){
    collection[id] = o;
  }

  this.remove = function(id){
    delete collection[id];
  }

  this.getById = function(id){
    return collection[id];
  }

  this.get = function(){
    return collection;
  }
}

var myAssoc = new AssocArray();
myAssoc.add("11",{"packageId": "11", "machineId": "1", "operationType": "Download"});
myAssoc.add("12",{ "packageId": "12", "machineId": "1", "operationType": "Download"});
myAssoc.add("14",{ "packageId": "14", "machineId": "1", "operationType": "Download"});

if(myAssoc.getById("10")) myAssoc.remove("10");
if(myAssoc.getById("14")) myAssoc.remove("14");

console.log(myAssoc.get());
于 2013-02-28T15:52:57.843 回答