例如:
array1 = [5, 1, 3];
array2 = [1 => 15, 2 => 20, 3 => 10, 4 => 5, 5 =>50 ];
差别在于...
diff = [2 => 20, 4=> 5];
array1 = [5, 1, 3];
array2 = [1 => 15, 2 => 20, 3 => 10, 4 => 5, 5 =>50 ];
diff = [2 => 20, 4=> 5];
我猜您的问题只是在声明array2
时有个小错误,这不是什么大问题。
无论如何,下面是一个小技巧,但它可以给您想要的结果:
array1 = [5, 1, 3];
array2 = {1: 15, 2: 20, 3: 10, 4: 5, 5: 50};
var result = {};
for (var i in array2) {
if (array1.indexOf(+i) < 0) {
result[i] = array2[i];
}
}
alert(JSON.stringify(result));
我的技巧是在indexOf
调用中使用+i
,因为你的“关联数组”的属性是字符串,但是你的array1
包含数字。一元运算符+
可以从字符串中生成一个数字。这有点儿取巧,但它是惯用的和被接受的JavaScript实践方法。
附录
正如RobG所指出的那样,indexOf
是一个ES5方法,所以如果你的JavaScript引擎是ES3或以下版本,则需要自己实现indexOf
。MDN上提供了一个实现示例。或者,您可以通过自己搜索数组来实现与indexOf
等效的操作。
首先,你的第二个数组应该是一个对象,并且不是有效的JavaScript,就像前两个评论者说的那样。以下是以对象形式呈现:
var object = { "1": 15, "2": 20, "3": 10, "4": 5, "5": 50 };
function findDiff(arr, obj)
{
var tempObj = clone(obj);
for (var i = 0; i < arr.length; i++)
{
var propId = arr[i];
if (tempObj[propId] !== undefined)
delete tempObj[propId];
}
return tempObj;
}
这个函数依赖于一个叫做clone
的函数,它确保通过值而不是引用将obj
复制到tempObj
中。这可以防止传递的对象被修改:
function clone(obj){
if(obj == null || typeof(obj) != 'object')
return obj;
var temp = obj.constructor(); // changed
for(var key in obj)
temp[key] = clone(obj[key]);
return temp;
}
var array = [5, 1, 3];
var object = { "1": 15, "2": 20, "3": 10, "4": 5, "5": 50 };
var diff = findDiff(array, object);
tempObj = obj
的赋值实际上没有任何有用的作用,该函数返回修改后的原始对象,而不是副本。此外,在尝试删除属性名称之前,应该检查它(参见ES5 delete operator),因为在严格模式下可能会抛出错误。 - RobGarray1 = [5, 1, 3];
array2 = [15, 20, 10, 5, 50 ];
您可能有这样一个函数:
function diff(arr1, arr2) {
// Copy arrays so don't affect originals
var t1 = arr1.slice();
var t2 = arr2.slice();
// sort t1
t1.sort();
// Remove members of arr2 from highest indexes to lowest
var i = t1.length;
while (i--) {
t2.splice(t1[i], 1);
}
return t2;
}
alert(diff(array1, array2)); // 15, 10, 50
JSON.stringify()
,并检查结果字符串的最左侧或最右侧字符。如果它是{
或}
,则您有一个关联数组/对象;如果是[
或]
,则它是一个数组。我想这可能会有点昂贵,取决于您的数组大小,但它可以完成工作。
然而...不存在免费的午餐,所有的动物都是成对出现的,所以这个解决方案只有在你根据原始定义一致的使用变量时才是合理的。
如果你定义了一个对象,如下所示:obj = [1,2,3]
,然后,在以后的某个时间点上,添加了一个值,如:obj['w'] = 'ww'
,JSON.stringify(obj)
将只会产生[1,2,3]
,但如果你再次调用obj['w']
,你仍然会得到ww
,这意味着这个值并没有被遗忘,它们只是不混合在一起。我想,在内部,JavaScript 保留了两个独立的变量表,一个用于对象,一个用于数组,无论哪个先定义,当用 stringify 打印时就会得到优先。
为了更加混淆事情,如果你先将变量定义为对象,但随后添加了一个数组键,也就是说
obj = {1: 11, 2: 22, 3: 33};
obj[4] = 44;
{"1":11, "2": 22, "3": 33, "4": 44} //sans the \", for better readibility
虽然有点混乱,但我想这就是为了一点无政府状态和易用性所付出的代价。
diff
应该只提供那些包含在array2
中但不在array1
中的 _值_。然而,array2
具有值15、20、10、5、50
,因此差异应该是[15、20、10、50]
,因为 1 和 3 只是array2
的 _键_。 虽然在 JS 对象符号和 Perl 哈希符号之间混淆很棒,但当我在短时间内同时进行两者或来回切换时,这种情况总会发生。 - yogibimbi