web-dev-qa-db-fra.com

JS immuable compare les structures imbriquées

J'ai 2 structures imbriquées newState et newState1

Mais quand je compare leurs, equals () ou Immutable.is () a retourné false . Les valeurs dans ces structures sont identiques.

Comment comparer correctement newState et 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 dans JSFiddle: https://jsfiddle.net/z3xuagwm/

9
Slava Minchonok

Il semble que immutablejs ne fait pas de conversion profonde, donc si votre valeur est object, elle reste objet.

Lorsque vous créez un objet différent à chaque étape de la mise à jour, ces objets étant traités différemment, vous devez également le convertir en objet Immutable.Map pour que la comparaison soit vraie.

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

18
fuyushimoya

Changez Immutable.Map en Immutable.fromJS dans vos fonctions Push (comme cela a été mentionné - seul fromJS effectuera une conversion en profondeur. Map, List, etc. ne le fera pas):

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

Qu'en est-il d'utiliser JSON.stringify?

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

Si vous savez qu'ils ne sont pas des objets circulaires et qu'ils ne contiennent pas de fonctions, je pense que c'est le moyen le plus rapide de les comparer.

0
kompupat