Immutable JS compare nested structures

女生的网名这么多〃 提交于 2019-11-30 01:53:10

问题


I have 2 nested structures newState and newState1.

But when I compare their, equals() or Immutable.is() returned false. The values in these structures identical.

How to correctly compare newState and 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/


回答1:


It seems that immutablejs don't do deep conversion, so if your value is object, it stays to be 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.

// 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>



回答2:


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):

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: {}
    }));
});



回答3:


What about using 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.



来源:https://stackoverflow.com/questions/32913458/immutable-js-compare-nested-structures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!