如何从数组对象中区分出差异?

时间:2019-09-06 11:29:47

标签: javascript arrays object

我现有的数组对象是

//existing object
var existing = [
{
'ProviderCode':'aa',
'msg':'....',
},{
'ProviderCode':'bb',
'msg':'....',
},{
'ProviderCode':'cc',
'msg':'....',
},{
'ProviderCode':'dd',
'msg':'....',
},{
'ProviderCode':'ee',
'msg':'....',
}];
我要比较的新对象
var new = [
{
'ProviderCode':'bb',
'msg':'....',
},{
'ProviderCode':'cc',
'msg':'....',
},{
'ProviderCode':'ee',
'msg':'....',
},{
'ProviderCode':'ff',
'msg':'....',
},{
'ProviderCode':'gg',
'msg':'....',
}];

我想基于两个数组对象生成相同的,删除和添加的数组,我可以获取相同的数组对象,但不能从对象中获取删除和添加的对象。

var same = [];   //bb, cc, ee   //these will be the match
var remove = []; //aa , dd      //will be remove from existing
var add = [];    //ff, gg       //will be consider as add

//I can get the same using below:
e.forEach(function(ev,ei,ea){
n.forEach(function(nv,ni,na){
	if( ev.ProviderCode === nv.ProviderCode ){
		s.push({ProviderCode:ev.ProviderCode,msg:"Same, do nothing"});
    }
});
});
/* //output:
[{
"ProviderCode": "bb",
"msg": "Same, do nothing"
}, {
"ProviderCode": "cc",
"msg": "Same, do nothing"
}, {
"ProviderCode": "ee",
"msg": "Same, do nothing"
}]
*/


//but how do I get remove and add array object?

//remove will be:
/* //output:
[{
"ProviderCode": "aa",
"msg": "removed"
}, {
"ProviderCode": "dd",
"msg": "removed"
}]
*/

//add will be:
/* //output:
[{
"ProviderCode": "ff",
"msg": "added"
}, {
"ProviderCode": "gg",
"msg": "added"
}]
*/

3 个答案:

答案 0 :(得分:2)

您可以为此使用Array.prototype.filterArray.prototype.find

let existing = [{ProviderCode:'aa'},{ProviderCode:'bb'},{ProviderCode:'cc'},{ProviderCode:'dd'},{ProviderCode:'ee'}];
let newData = [{ProviderCode:'bb'},{ProviderCode:'cc'},{ProviderCode:'ee'},{ProviderCode:'ff'},{ProviderCode:'gg'}];


let added = newData.filter(d => !existing.find(e => d.ProviderCode === e.ProviderCode));
console.log("ADDED:", added);

let removed = existing.filter(d => !newData.find(e => d.ProviderCode === e.ProviderCode));
console.log("REMOVED:", added);

let same = newData.filter(d => existing.find(e => d.ProviderCode === e.ProviderCode));
console.log("SAME:", same);

使用像lodash这样的库,这会容易一些:

let existing = [{ProviderCode:'aa'},{ProviderCode:'bb'},{ProviderCode:'cc'},{ProviderCode:'dd'},{ProviderCode:'ee'}];
let newData = [{ProviderCode:'bb'},{ProviderCode:'cc'},{ProviderCode:'ee'},{ProviderCode:'ff'},{ProviderCode:'gg'}];

console.log("ADDED:"  , _.differenceBy(newData, existing, 'ProviderCode'));
console.log("REMOVED:", _.differenceBy(existing, newData, 'ProviderCode'));
console.log("SAME:"   , _.intersectionBy(newData, existing, 'ProviderCode'));
<script src="https://unpkg.com/lodash@4.17.15/lodash.min.js"></script>

答案 1 :(得分:1)

您可以使用这个小“库”,它为JS Map对象提供设置操作:

function mapUnion(m1, m2) {
    let m = new Map();

    for (let [k, v] of m1)
        m.set(k, v);
    for (let [k, v] of m2)
        m.set(k, v);

    return m;
}

function mapIntersection(m1, m2) {
    let m = new Map();

    for (let [k, v] of m1)
        if (m2.has(k))
            m.set(k, v);

    return m;
}

function mapDifference(m1, m2) {
    let m = new Map();

    for (let [k, v] of m1)
        if (!m2.has(k))
            m.set(k, v);

    return m;
}

有了这个,您可以将两个数组都转换为Maps:

let m1 = new Map(oldArray.map(x => [x.ProviderCode, x]))
let m2 = new Map(newArray.map(x => [x.ProviderCode, x]))

,然后用这些做任何您想做的事,

console.log(mapIntersection(m1, m2))  // bb=>..., cc=>..., ee=>...
console.log(mapDifference(m1, m2))  // aa=>..., dd=>...

如果需要数组作为结果:

commonObjects = Array.from(mapIntersection(m1, m2).values())

答案 2 :(得分:1)

您可以带几套,并为每次更改获取所需的物品。

const
    providerCode = ({ ProviderCode }) => ProviderCode;

var existingData = [{ ProviderCode: 'aa' }, { ProviderCode: 'bb' }, { ProviderCode: 'cc' }, { ProviderCode:'dd' }, { ProviderCode: 'ee' }],
    newData = [{ ProviderCode: 'bb' }, { ProviderCode: 'cc' }, { ProviderCode: 'ee' }, { ProviderCode: 'ff' }, { ProviderCode: 'gg' }],
    existingSet = new Set(existingData.map(providerCode)),
    newSet = new Set(newData.map(providerCode)),
    same = [...existingSet].filter(Set.prototype.has, newSet),
    add = [...newSet].filter(v => !existingSet.has(v)),
    remove = [...existingSet].filter(v => !newSet.has(v));

console.log(...same);
console.log(...add);
console.log(...remove);