[英]How do I find and remove an object from an array based on what I know about the contents of that object?
For the following: 对于以下内容:
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);
I always get -1
as a result. 结果我总是得到
-1
。 Why is that? 这是为什么?
I need to be able to remove an object from an array. 我需要能够从数组中删除一个对象。
[Note in reference to the original wording of your question: There is no JSON in your question actually; [请注意问题的原始措辞:实际上,您的问题中没有JSON; JSON refers to object notation.
JSON是指对象符号。 What you have inside your array and your
indexOf()
call are object literals, represented by {}
with optional properties inside.] 数组和
indexOf()
调用中包含的是对象文字,由{}
表示,内部带有可选属性。]
The problem is that the object literal you create inside your indexOf()
call is a new object unto itself and therefore not equal to anything inside the array arr
. 问题在于您在
indexOf()
调用中创建的对象文字本身就是一个新对象,因此不等于数组arr
任何内容。 Instead, you have to loop through all the properties in each object and check their equivalence. 相反,您必须遍历每个对象中的所有属性并检查它们的等效性。 I wrote this function quickly now and you can test it in the JSFiddle link at the bottom of this answer.
我现在快速编写了此函数,您可以在此答案底部的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;
}
}
}
You feed it two objects, so in your question that would be: 您向它提供了两个对象,因此在您的问题中将是:
compareObjs(arr[1], { "packageId": "12", "machineId": "1", "operationType": "Download" });
This should return true. 这应该返回true。 If the two objects aren't equivalent then it will return false.
如果两个对象不相等,则它将返回false。
I'm guessing you would want to use this to check the position of a particular package in the array, in which case you would probably need to loop through your array checking each object in it for equivalence, like so: 我猜想您将要使用它来检查特定包在数组中的位置,在这种情况下,您可能需要遍历数组,检查其中的每个对象是否相等,如下所示:
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;
}
Here r
should give you the first position in which an equivalent object is found. 在这里
r
应该给您找到等同对象的第一个位置。
You can then remove the object from the array with reference to r
, using the splice()
method like so: 然后可以使用
splice()
方法,参照r
,从数组中删除对象,如下所示:
arr.splice(r, 1);
You might want to drop this code into a function too but I don't know the structure of the rest of your programme so will leave you to ponder that! 您可能也希望将此代码放入函数中,但是我不知道程序其余部分的结构,因此请您仔细考虑!
JSFiddle here . JSFiddle在这里 。 (You will need to open the browser console to view the results.)
(您将需要打开浏览器控制台以查看结果。)
The {}
object literal you are creating is actually a different object than the object in arr
, so they cannot be compared directly and indexOf
will fail. 您正在创建的
{}
对象文字实际上是与arr
的对象不同的对象,因此无法直接比较它们,并且indexOf
将失败。 You have to use good old fashioned iteration: 您必须使用良好的老式迭代:
arr.filter(function (elem) {
return elem.packageId != 12
|| elem.machineId != 1
|| elem.operationType != 'Download';
});
You can of course also compare to an object if you need. 当然,如果需要,您也可以与对象进行比较。
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;
});
I suggest you another possible solution. 我建议您另一种可能的解决方案。
If you can modify your data structure, use an Object in order to store your data, an shape it as an associative array: 如果可以修改数据结构,请使用一个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"];
Advantages: 好处:
You could also arrange a class to manage your data: 您还可以安排一个班来管理数据:
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());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.