2013-02-24 32 views
2

我有两个阵列oldArraynewArray。当新值被放入newArray时,我想要与oldArray进行比较并提取新值。发现两个哈希阵列的区别

在这些数组中,我存储散列。

例如。

oldArray = [] 
newArray = [{"one": 1}] 

我需要找到新的元素,这是{"one": 1}

使用underscore.js我可以做这样的事情:

newElement = _.difference(newValue, oldValue) 

这工作正常的第一次,但是当我回去并向阵列添加更多:

oldArray = [{"one": 1}] 
newArray = [{"one": 1},{"two": 2}] 

而且做同样的事newElement = _.difference(newValue, oldValue)

我得到[{"one": 1},{"two": 2}]作为新对象回来......是因为我在比较对象而不是数值吗?有一个更好的方法吗。

以上是一个例子,但离我的应用我从控制台

oldValue map.js:85 
[Object] 
0: Object 
$$hashKey: "007" 
address: "england" 
latLng: GeoCode 
__proto__: Object 
length: 1 
__proto__: Array[0] 

newValue map.js:83 
[Object, Object] 

0: Object 
$$hashKey: "007" 
address: "england" 
latLng: GeoCode 
__proto__: Object 

1: Object 
$$hashKey: "009" 
address: "france" 
latLng: GeoCode 
__proto__: Object 
length: 2 
__proto__: Array[0] 

当我比较这两个,我会被拉这样的:

[Object, Object] 
0: Object 
$$hashKey: "007" 
address: "england" 
latLng: GeoCode 
__proto__: Object 

1: Object 
$$hashKey: "009" 
address: "france" 
latLng: GeoCode 
__proto__: Object 
length: 2 
__proto__: Array[0] 

我使用AngularJS并强调在这个项目目前。

也许有这样做更好。我只需要从该数组中取出“不同”对象。所以我可以用它来做其他事情。它并不总是最后一个元素。

UPDATE

我也试过JavaScript的数组设置数学库,并使用.substract但具有相同的结果。这意味着哈希正在改变 - 但它们看起来不像我

为了得到这些oldArraynewArray我正在使用Angular $ watch。

+0

你能提供一个像jsfiddle.net这样的简化测试用例吗? – Dogbert 2013-02-24 16:23:02

回答

1

如果$$hashKey始终是唯一的,那么您可以创建两个对象并使其散列的密钥为$$hashKey

newObject[myObject["$$hashKey"]] = myObject; 

然后

var difference = _.omit(newObject, _.keys(oldObject)); 

会给你包含仅包含已在NEWOBJECT,但不老的键/值对的对象。

如果没有唯一的键,不太方便的方法是将对象序列化并反序列化为字符串,然后使用_.difference

+0

$$ hashKey始终是独立的 – 2013-02-24 16:30:39

+0

这确实有效,这真的很有趣。我想知道为什么其他函数不起作用 – 2013-02-24 16:33:23

+0

在JavaScript中,对象之间的比较是通过严格的身份来完成的,而不是通过它们的键/值对来完成的。所以'foo = {5:6}; bar = {5:6}; foo == bar; // false' – 2013-02-24 16:36:24

0

不久前,我遇到了一个类似的AngularJS挑战。虽然我不确定我可以给你如何管理这个问题的绝对最佳答案,但我可以这样说:

第一:确保您正确使用$ watch。它需要3个参数:

  • watchExpression - {(function()| string)} - 在每个$ digest循环上评估的表达式。返回值的更改会触发对侦听器的调用。 字符串:评估为表达式 函数(作用域):以当前作用域作为参数调用。
  • listener(可选) - {(function()| string)=} - 每当watchExpression的返回值改变时调用回调。 字符串:评估为表达式 函数(newValue,oldValue,scope):以当前值和先前值作为参数调用。
  • objectEquality(可选) - {boolean =} - 比较对象是否相等,而不是参考。

最后一块是特别重要的。你想在你的情况下要留意objectEquality,所以一定要使用$看像这样:

$scope.$watch('watchObject', fn({}), true);

注意使用true如上第三PARAM。请参阅Angular Scope Docs。第二:在区分Angular对象时,我认为围绕$$ hashKeys比较的答案可能会有很大的意义。您也可以考虑编写自己的差异函数,具体取决于您想要返回的内容。如果你想返回差异,你只是看差异的基本对象,请尝试类似:jQuery objectDiff

第三:如果你想比较一个对象与嵌套对象和/或阵列里面,事情会得到难。我写了一个没有经过优化的方法,如果你需要的话,我会很高兴地发出更多的光。

祝你好运!

+0

谢谢你对我这个闪耀的光芒! – 2013-02-24 17:41:44

+0

没有汗!享受Angular bliss :)的路径 – nauce 2013-02-24 17:46:40