2016-11-18 10 views
2

Я пытаюсь найти разницу между элементами в сложном массиве.Разница между объектами в массиве

У меня есть список массива следующим образом:

[ 
    [{ 
     id: 123, 
     list: [{ 
      name: "Vimal", 
      status: "Pass" 
     }, { 
      name: "Selvam", 
      status: "Pass" 
     }] 
    }], 
    [{ 
     id: 124, 
     list: [{ 
      name: "Vimal", 
      status: "Pass" 
     }, { 
      name: "Selvam", 
      status: "Fail" 
     }, { 
      name: "Raj", 
      status: "Pass" 
     }] 
    }] 
] 

Я хотел бы получить разницу между list следующим образом:

[{ 
    id: 123, 
    list: [{ 
     name: "Selvam", 
     status: "Pass" 
    }] 
}, { 
    id: 124, 
    list: [{ 
     name: "Selvam", 
     status: "Fail" 
    }, { 
     name: "Raj", 
     status: "Pass" 
    }] 
}] 

Я думал в цикле каждый элемент и сравнить с соседним затем сохраните различия во временной переменной. Но это звучит слишком громоздко. Я просто хотел, чтобы ваше мнение о том, как изменить способ поиска этой проблемы. Указатели были бы более полезными. В противном случае, есть ли библиотека, которая могла бы легко решить эту проблему?

Редактировать 1: Обратите внимание: список будет не длиннее 2. Размер динамический. И сравнение должно происходить между всеми элементами.

+0

Имеет ли значение, если разница попадает, когда они просто не в порядке? –

+0

@BradBumbalough: Не имеет значения –

+0

Удивительный! и хотите ли вы узнать, что * изменилось или просто изменилось? –

ответ

1

Если вы хотите разницу, вам понадобится Перекресток двух объектов.

В вашем случае вам необходимо знать, что отличает первое. Затем вы можете взять это и использовать его для удаления свойств, чтобы знать симметричная разница.

Это является очень сложной проблемой, поскольку, если сравнение массивов с О (п). В моем случае ниже я просто сравнил значения JSON. Это удобно для вашей проблемы, но это не рекомендуется для более сложного массива объектов.

Примечание: Я не знаю, почему вы решили обернуть свои объекты внутри массива без вложенного массива? Я удалил скобки, чтобы упростить логику. См. Измененный JSON. Вы можете легко добавить это обратно в логику необходимости.

var dataArr = getSampleData(); 
 
var intersectObj = findObjectIntersection(dataArr[0], dataArr[1], {}); 
 

 
document.body.innerHTML = '<pre>' + JSON.stringify(intersectObj, null, 4) + '</pre>'; 
 

 
// Iterate over all keys and find similar key-values. 
 
function findObjectIntersection(obj1, obj2, obj3) { 
 
    var keys1 = Object.keys(obj1); // Object 1 keys 
 
    var keys2 = Object.keys(obj2); // Object 2 keys 
 
    var keysL = keys1.length > keys2.length ? keys1 : keys2; 
 
    var keysS = keysL === keys1 ? keys2 : keys1; 
 
    var keysD = keysL.filter(function(key) { 
 
    return keysS.indexOf(key) > -1; 
 
    }); 
 
    for (var i = 0; i < keysD.length; i++) { 
 
    var currKey = keysD[i]; 
 
    var val1 = obj1[currKey]; 
 
    var val2 = obj2[currKey]; 
 

 
    if (isValue(val1) && isValue(val2)) { 
 
     if (val1 === val2) { 
 
     obj3[currKey] = val1; 
 
     } 
 
    } else if (isArray(val1) && isArray(val2)) { 
 
     obj3[currKey] = findArrayIntersectionSimple(val1, val2, []); 
 
    } 
 
    } 
 
    return obj3; 
 
} 
 

 
// Only compare values by JSON. 
 
function findArrayIntersectionSimple(arr1, arr2, arr3) { 
 
    var arrL = arr1.length > arr2.length ? arr1 : arr2; 
 
    var arrS = arrL === arr1 ? arr2 : arr1; 
 
    for (var i = 0; i < arrL.length; i++) { 
 
    for (var j = 0; j < arrS.length; j++) { 
 
     var val1 = JSON.stringify(arrL[i]); 
 
     var val2 = JSON.stringify(arrS[j]); 
 
     if (val1 === val2) { 
 
     arr3.push(arrL[i]); 
 
     } 
 
    } 
 
    } 
 
    return arr3; 
 
} 
 

 
function isFunction(obj) { 
 
    return {}.toString.apply(obj) === '[object Function]'; 
 
} 
 

 
function isArray(obj) { 
 
    return {}.toString.apply(obj) === '[object Array]'; 
 
} 
 

 
function isObject(obj) { 
 
    return {}.toString.apply(obj) === '[object Object]'; 
 
} 
 

 
function isValue(obj) { 
 
    return !isObject(obj) && !isArray(obj); 
 
} 
 

 
function getSampleData() { 
 
    return [{ 
 
    id: 123, 
 
    list: [{ 
 
     name: "Vimal", 
 
     status: "Pass" 
 
    }, { 
 
     name: "Selvam", 
 
     status: "Pass" 
 
    }] 
 
    }, { 
 
    id: 124, 
 
    list: [{ 
 
     name: "Vimal", 
 
     status: "Pass" 
 
    }, { 
 
     name: "Selvam", 
 
     status: "Fail" 
 
    }, { 
 
     name: "Raj", 
 
     status: "Pass" 
 
    }] 
 
    }]; 
 
}

+0

Наверное, я не общался должным образом. Вы предположили, что список всегда будет длиной 2. Но в моем случае длина будет динамичной. –

0

Как Mr. Polywhirl говорит, вы хотите, чтобы получить симметричную разницу между двумя массивами.

Как это бывает, у Lodash есть функция полезности для этого: xorWith.

Вот пример использования:

var symmetricDifference = _.xorWith(array1, array2, comparisonFn); 

В этом примере xorWith() сравнивает значения из array1 и array2 с помощью функции comparisonFn.

Поскольку значения ваших массивов являются объектами, вам необходимо использовать функцию сравнения, которая глубоко проверяет объекты на равенство. У Lodash есть такая функция сравнения: isEqual.

Таким образом, для случая использования, вы можете получить симметричную разницу между вашими двумя списками (назовем их list1 и list2) что-то вроде этого кода:

var symmetricDifference = _.xorWith(list1, list2, _.isEqual); 
+0

Я редактировал свой вопрос. Я не хочу сравнивать два массива, я бы хотел сравнить элементы. –

Смежные вопросы