javascript 不可变 JS 比较嵌套结构
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32913458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Immutable JS compare nested structures
提问by Slava Minchonok
I have 2 nested structures newStateand newState1.
我有 2 个嵌套结构newState和newState1。
But when I compare their, equals() or Immutable.is() returned false. The values in these structures identical.
但是当我比较它们时, equals() 或 Immutable.is() 返回false。这些结构中的值相同。
How to correctly compare newStateand newState1?
如何正确比较newState和newState1?
var grid = {
editable: false,
widgets: [{
name: 'Some widget',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}, {
name: 'Some widget1',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}]
};
var state = Immutable.fromJS(grid);
var newState = state.updateIn(['widgets'], function (list) {
return list.push(Immutable.Map({
name: 'Some widget2',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}));
});
var newState1 = state.updateIn(['widgets'], function (list) {
return list.push(Immutable.Map({
name: 'Some widget2',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}));
});
console.log(state.toJS(), newState.toJS(), newState1.toJS());
console.log(newState.equals(newState1)); //false
Code in JSFiddle: https://jsfiddle.net/z3xuagwm/
JSFiddle 中的代码:https://jsfiddle.net/z3xuagwm/
回答by fuyushimoya
It seems that immutablejs don't do deep conversion, so if your value is object, it stays to be object.
好像 immutablejs 不做深度转换,所以如果你的值是 object,它就一直是 object。
As you're creating different object in each update step, and those objects will be treat different when you compare to each other, so you should also convert it to Immutable.Map object, to make the compare be true.
由于您在每个更新步骤中创建不同的对象,并且当您相互比较时,这些对象将被区别对待,因此您还应该将其转换为 Immutable.Map 对象,以使比较为真。
// Primitives.
var test1 = Immutable.Map({
a: 'a',
b: 'b',
c: 'c'
});
var test2 = Immutable.Map({
a: 'a',
b: 'b',
c: 'c'
});
console.log('Test primitive', test1.equals(test2)); // true
// Object
test1 = Immutable.Map({
a: 'a',
b: 'b',
c: {}
});
test2 = Immutable.Map({
a: 'a',
b: 'b',
c: {}
});
console.log('Test object', test1.equals(test2)); // false
// Its because
var a = {};
var b = {};
console.log('a === b?', a === b); // false
// Convert
test1 = Immutable.Map({
a: 'a',
b: 'b',
c: Immutable.Map({})
});
test2 = Immutable.Map({
a: 'a',
b: 'b',
c: Immutable.Map({})
});
console.log('Test converted', test1.equals(test2)); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.5/immutable.min.js"></script>
回答by Geoffrey Abdallah
Change Immutable.Map to Immutable.fromJS in your push functions (as has been mentioned - only fromJS will do a deep conversion, Map,List etc won't):
在推送函数中将 Immutable.Map 更改为 Immutable.fromJS(如前所述 - 只有 fromJS 会进行深度转换,Map、List 等不会):
var newState = state.updateIn(['widgets'], function (list) {
return list.push(Immutable.fromJS({
name: 'Some widget2',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}));
});
var newState1 = state.updateIn(['widgets'], function (list) {
return list.push(Immutable.fromJS({
name: 'Some widget2',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}));
});
回答by kompupat
What about using JSON.stringify
?
怎么用JSON.stringify
?
JSON.stringify(values) !== JSON.stringify(anothervalue);
If you know they are not circular objects, and do not contain functions, I think it's the fastest way to compare them.
如果您知道它们不是圆形对象,并且不包含函数,我认为这是比较它们的最快方法。