diff icon indicating copy to clipboard operation
diff copied to clipboard

Work with array of objects

Open NewOldMax opened this issue 8 years ago • 11 comments

Hi, In my case, I have some array of objects ordered by name key. This code

var lhs = [{id: 1, name: "a"}, {id: 2, name: "b"}, {id: 3, name: "c"}]; // old array, given from backend previous time
var rhs = [{id: 2, name: "b"}, {id: 3, name: "c"}, {id: 1, name: "e"}]; // new array, git from backend now

deepDiff(lhs, rhs);

says that I have 6 changes, but in real only 1 object is changed {id: 1, name: "e"}. Is there a way to get something like "1 edition in {id: 1, name: "e"}"? I want to use it for a making new items for user, like "hey, this item has been changed". Can I achieve this with your library?

NewOldMax avatar Apr 29 '17 12:04 NewOldMax

I have the same problem when I delete the first element of an array. It creates n differences for an array of n elements.

var lhs =  ["1", "2", "3", "4"]; // old array, given from backend previous time
var rhs = ["2", "3", "4"];// new array, git from backend now

deepDiff(lhs, rhs);

result:

[{
	"kind": "E",
	"path": [0],
	"lhs": "1",
	"rhs": "2"
}, {
	"kind": "E",
	"path": [1],
	"lhs": "2",
	"rhs": "3"
}, {
	"kind": "E",
	"path": [2],
	"lhs": "3",
	"rhs": "4"
}, {
	"kind": "A",
	"index": 3,
	"item": {
		"kind": "D",
		"lhs": "4"
	}
]

I just think it should return [{"kind": "A","index": 0,"item": {"kind": "D","lhs": "1"}]

tarekz avatar Jun 09 '17 23:06 tarekz

I think the solution could be to, instead of always comparing items in both arrays index-by-index, provide an option to pass a function which specifies how to compare items within an array by some kind of unique identifier or hash. Typically this will just be item => item.id (as in the first given example) or even just item => item (second example).

When such a function is supplied, it would be used to detect whether an item in one array exists in the other. Note that if it does and it is an object (or other array), these objects themselves still need to be compared because they might have other changes.

When the function is not supplied, the current index-by-index comparison can still be used as fallback.

vincentsels avatar Nov 10 '17 09:11 vincentsels

@vincentsels I agree with your idea. We need a function to tell the library how to compare objects (e.g. by item.id of each object instead of the array key).

Is there any workaround yet or do we need to wait for a PR?

pschaub avatar Jan 10 '18 13:01 pschaub

@pSchaub I'm using something like this (one level diff)

import deepDiff from 'deep-diff';

function arrayCompare(arrFirst, arrSecond, propName) {
    const arrDiff = [];
    let fields;
    let obj;
    for (let key2 in arrSecond) {
        obj = arrFirst.filter(o => o[propName] === arrSecond[key2][propName]);
        obj = obj[0];
        if (obj !== undefined) {
            fields = deepDiff(obj, arrSecond[key2]);
        }
        if (fields !== undefined) {
            arrDiff.push({ key: key2, fields });
        }
    }
    if (arrDiff.length) {
        return arrDiff;
    }
    return false;
}

const diff = arrayCompare(firstArr, secondArr, 'id');

NewOldMax avatar Jan 10 '18 13:01 NewOldMax

btw: this issue is a duplicate, see #37

pschaub avatar Jan 10 '18 13:01 pschaub

@NewOldMax But your solution will not work with nesting (e.g. array > object > array > object > ..), right?

pschaub avatar Jan 10 '18 13:01 pschaub

Didn't test with nested, in my cases I have only first-level differences

NewOldMax avatar Jan 10 '18 13:01 NewOldMax

@NewOldMax I don't see any kind of recursion in your code so this shouldn't work in nested situations. We really need a fix inside the library itself. But thanks for your workaround for 1st-level-differences.

pschaub avatar Jan 10 '18 13:01 pschaub

any progress?

kenberkeley avatar Jul 31 '18 12:07 kenberkeley

@kenberkeley We switched to https://github.com/benjamine/jsondiffpatch to solve our nested situation. Maybe this will help you until anybody will implement a way into this package.

pschaub avatar Aug 02 '18 14:08 pschaub

Any updates in regards to this issue.

kingasare avatar Oct 11 '18 10:10 kingasare