2016-11-18 106 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

如果你想要的差異,你將需要十字路口的兩個對象。

就你而言,你需要知道什麼是不同的。然後你可以拿下它並使用它去除屬性,以知道對稱差異

這是一個非常複雜的問題,因爲比較陣列如果爲O(n 2 。在我的情況下,我只比較了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()使用comparisonFn函數比較array1array2的值。

由於數組的值是對象,因此需要使用比較函數來深入檢查對象是否相等。 Lodash具有這樣的比較功能:isEqual

因此,對於您的使用情況下,你可能會得到你的兩個表之間的對稱差(讓我們稱他們爲list1list2),像這樣的東西代碼:

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

我編輯了我的問題。我不想比較兩個數組,我想比較兩個元素。 –