找到两个哈希数组的差异

时间:2013-02-24 15:48:35

标签: javascript angularjs underscore.js

我有两个阵列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和Underscore。

也许有更好的做法。我只需要从该数组中提取“不同”对象。所以我可以用它来做别的事。它并不总是最后一个元素。

更新

我也尝试过使用JavaScript数组库和使用.substract,但结果相同。这必然意味着哈希正在发生变化 - 但它们看起来并不像我这样

要获取这些oldArraynewArray我正在使用Angular $ watch。

2 个答案:

答案 0 :(得分:1)

如果$$hashKey始终是唯一的,那么您可以创建两个对象,并使哈希的键为$$hashKey

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

然后

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

将为您提供一个对象,其中包含仅包含newObject中的键/值对但不包含旧对象的键/值对。

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

答案 1 :(得分:0)

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

首先:确保你正确使用$ watch。需要3个参数:

  • watchExpression - {(function()| string)} - 在每个$摘要周期计算的表达式。返回值的更改会触发对侦听器的调用。 string:评估为表达式 function(scope):以当前范围作为参数调用。
  • listener(可选) - {(function()| string)=} - 只要watchExpression的返回值发生变化,就会调用Callback。 string:评估为表达式 function(newValue,oldValue,scope):使用当前值和先前值作为参数调用。
  • objectEquality(可选) - {boolean =} - 比较对象是否相等而非参考。

最后一件作品特别重要。你希望在你的情况下观察objectEquality,所以一定要像这样使用$ watch:

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

请注意使用true作为上面的第三个参数。请参阅Angular Scope Docs

中的详情

第二:在区分Angular对象时,我认为围绕比较$$ hashKeys的答案可能很有意义。您也可以考虑编写自己的diff函数,具体取决于您要返回的内容。如果您想要返回差异并且只是想要区分基本对象,请尝试以下操作:jQuery objectDiff

第三:如果你想比较一个Object与其中的嵌套对象和/或数组,事情将变得困难。我写了一个未优化的方法,如果你需要的话,我会很高兴地发现它。

祝你好运!