web-dev-qa-db-ja.com

不変のJSはネストされた構造を比較します

2つのネストされた構造newStateおよびnewState1があります。

しかし、それらを比較すると、equals()またはImmutable.is()がfalseを返しました。これらの構造の値は同じです。

newStatenewState1を正しく比較する方法は?

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

JSFiddleのコード: https://jsfiddle.net/z3xuagwm/

12
Slava Minchonok

Immutablejsはディープコンバージョンを行わないようです。そのため、値がオブジェクトの場合、オブジェクトのままです。

各更新ステップで異なるオブジェクトを作成しているため、これらのオブジェクトは互いに比較すると異なる扱いになるため、比較を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>
19
fuyushimoya

Push関数で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: {}
    }));
});
10

JSON.stringifyの使用についてはどうですか?

JSON.stringify(values) !== JSON.stringify(anothervalue);

それらが循環オブジェクトではなく、関数も含まれていないことがわかっている場合、それらを比較する最も速い方法だと思います。

0
kompupat