Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比较两个数组,并通过使用javascript保留现有对象来更新新值_Javascript_Arrays - Fatal编程技术网

比较两个数组,并通过使用javascript保留现有对象来更新新值

比较两个数组,并通过使用javascript保留现有对象来更新新值,javascript,arrays,Javascript,Arrays,下面是我的两个数组。我想比较它们,结果数组应该包含更新的值。Id是常见的。。 阵列跨越n个级别,即没有固定级别 第一个数组,即更新前的数组 var parentArray1=[ { "id": 1, "name": "test", "context": [ { "id": 1.1, "name": "test 1.1" }

下面是我的两个数组。我想比较它们,结果数组应该包含更新的值。Id是常见的。。 阵列跨越n个级别,即没有固定级别

第一个数组,即更新前的数组

var parentArray1=[
    {
        "id": 1,
        "name": "test",
        "context": [
            {
                "id": 1.1,
                "name": "test 1.1"
            }
        ]
    },
    {
        "id": 2,
        "name": "test"
    },
    {
        "id": 3,
        "name": "test",
        "context": [
            {
                "id": 3.1,
                "name": "test 3.1"
            }
        ]
    },
    {
        "id": 4,
        "name": "test"
    }
]
我执行的操作是

1.添加新项目 2.更新现有项目

作为这两个操作的结果,我将在不同的数组中获得更改的值。。 即

现在,我已经编写了一个通用函数,该函数在parentArray1中循环,并使用唯一的属性。我需要添加一个新项(如果该项位于changedArray中),或者在任何级别更新一个现有项

结果数组应为

[
    {
        "id": 1,
        "name": "test",
        "context": [
            {
                "id": 1.1,
                "name": "Changed test 1.1"
            }
        ]
    },
    {
        "id": 2,
        "name": "test"
    },
    {
        "id": 3,
        "name": "test",
        "context": [
            {
                "id": 3.1,
                "name": "test 3.1"
            }
        ]
    },
    {
        "id": 4,
        "name": "test"
    },
    {
        "id": 5,
        "name": "test5"
    }
]
通用功能:

compareArray(parentArray1, changedArray, ["id"]);

        function compareArray(array1, array2, propertyArray) {
            var newItem = new Array();
            array2.map(function(a1Item) {
                array1.map(function(a2Item) {
                    / If array loop again /
                    if (a2Item.constructor === Array) {
                        compareArray(a2Item, a1Item)
                    } else {
                        / loop the property name to validate /
                        propertyArray.map(function(property) {
                            if (a2Item[property]) {
                                if (a2Item[property] === a1Item[property]) {
                                    a2Item = a1Item
                                } else {
                                    var isAvailable = _.find(newItem, function(item) {
                                        return item[property] === a1Item[property]
                                    })
                                    if (!isAvailable) {
                                        newItem.push(a1Item);
                                    }
                                }
                            }
                        })
                    }

                });
            });

            / Insert the new item into the source array /
            newItem.map(function(item) {
                array1.push(item);
            });
            console.log("After Compare : " + array1);
        }

我建议使用一个临时对象来引用
id
,如果存在则更新,如果不存在则推送

var parentArray1=[{“id”:1,“name”:“test”,“context”:[{“id”:1.1,“name”:“test 1.1”}],{“id”:2,“name”:“test”},{“id”:3,“name”:“test”,“context”:[{“id”:3.1,“name”:“test 3.1”}],{“id”:4,“name”:“test”}],
changedArray=[{“id”:1,“名称”:“test1”,“上下文”:[{“id”:1.1,“名称”:“Changed test 1.1”}],{“id”:5,“名称”:“test5”}];
函数插入(数组、数据){
功能iter(阵列){
array.forEach(函数(a){
如果(!('id'在a中)){
返回;
}
如果(o[a.id]!==a){
o[a.id]=a;
}
Object.keys(a).forEach(函数(k){
isArray(a[k])&iter(a[k]);
});
});
}
var o={};
iter(阵列);
data.forEach(函数(a){
if(o[a.id]){
Object.keys(a).forEach(函数(k){
o[a.id][k]=a[k];
});
返回;
}
数组。推送(a);
});            
}
插入(parentArray1,changedArray);

document.write(“”+JSON.stringify(parentArray1,0,4)+’这是我想到的:

function compareArray(originalArray, destinationArray, propertyArray) {
            var newItem = new Array(), processedItem = new Array();
            for (var i = 0; i < originalArray.length; i++) {
                var sourceElement = originalArray[i];

                for (var j = 0; j < destinationArray.length; j++) {
                    var destinationElement = destinationArray[j];
                    var isUpdated = false;

                    if (sourceElement.constructor === Array) {
                        compareArray(sourceElement, destinationElement, propertyArray);
                    } else {
                        /* loop the property name to validate */

                        propertyArray.map(function(property) {
                            if (sourceElement[property]) {
                                if (sourceElement[property] === destinationElement[property]) {
                                    originalArray[i] = _.clone(destinationElement);
                                    isUpdated = true;
                                    return;
                                } else {
                                    var isAvailable = _.find(newItem, function(item) {
                                        return item[property] === destinationElement[property];
                                    });
                                    if (!isAvailable) {
                                        var isAlreadyProcessed = _.find(processedItem, function(item) {
                                            return item[property] === destinationElement[property];
                                        });
                                        if(!isAlreadyProcessed){
                                            newItem.push(destinationElement);
                                        }
                                    }
                                }
                            }
                        });
                    }
                    if (isUpdated === true) {
                        break;
                    }
                }
                processedItem.push(sourceElement);
            }
                newItem.map(function(item) {
                    originalArray.push(item);
                });

                return originalArray;
        }
功能sameKeys(o1、o2、按键){
对于(变量i=0;i1)
抛出“为同一组合键找到多个可能的对象”
阵列拼接(索引[0],1);
}
}
功能比较阵列(a1、a2、键阵列){
a2.forEach(功能(it2){
var it1s=a1.过滤器(功能(it){
返回sameKeys(it2、it、keyArray);
});
var-it1;
如果(!it1s.长度){
it1=克隆(it2);
a1.推动(it1);
}否则{
如果(it1s.length>1)
抛出“为同一组合键找到多个可能的对象”
it1=it1s[0];
扩展(it1、it2、keyArray);
}
如果(it2.移除的ID){
it2.removedIds.forEach(函数(ids){
removeFromArray(a1、ID、keyArray);
});
}
});
}
comparararray(parentArray1,changedArray,['id'])一起使用

请注意,它不适用于包含函数的对象。另外,如果数组很大,可能更好的解决方案是按键对两个数组进行排序,然后始终从最后找到的对象开始查找。我现在只有这些了

用Nina的一些概念和一些代码的清理更新了它

据我所知,您只想添加属性。所以扩展({a:{b:2}},{a:{c:3}})将导致{a:{b:2,c:3}}。如果这不是你想要的,让我知道

我还添加了删除ID的功能。如果数组中的任何对象包含形式为
[{id:4},{id:5}]
removedid
数组,则具有这些id的项将被删除
function sameKeys(o1, o2, keys) {
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        if (!o1.hasOwnProperty(key) || !o2.hasOwnProperty(key))
            throw 'compared objects do not have the key ' + key;
        if (o1[key] !== o2[key])
            return false;
    }
    return true;
}

function isNothing(o) {
    return typeof(o) === 'undefined' || o === null;
}

// this does not work if objects have functions as properties
function clone(o) {
    if (isNothing(o))
        return o;
    return JSON.parse(JSON.stringify(o));
}

function extend(o1, o2, keys) {
    if (isNothing(o2))
        return;
    if (isNothing(o1))
        throw ('first parameter cannot be empty');
    if (typeof(o1) != 'object' || typeof(o2) != 'object')
        throw ('extend only works on objects');
    Object.keys(o2).forEach(function (key) {
        var newVal = o2[key];
        if (o1.hasOwnProperty(key)) {
            if (isNothing(newVal)) {
                delete o1[key];
            } else
                if (Array.isArray(newVal)) {
                    compareArray(o1[key], newVal, keys);
                } else {
                    switch (typeof(newVal)) {
                    case 'object':
                        extend(o1[key], newVal, keys);
                        break;
                    case 'boolean':
                    case 'number':
                    case 'string':
                        o1[key] = newVal;
                        break;
                    default:
                        throw 'not supported property type: ' + typeof(newVal);
                    }
                }
        } else {
            o1[key] = clone(newVal);
        }
    });
}

function removeFromArray(arr, ids, keyArray) {
    var indexes = [];
    var it1s = arr.forEach(function (it, idx) {
            if (sameKeys(ids, it, keyArray)) {
                indexes.push(idx);
            } else {
                Object.keys(it).forEach(function (key) {
                    var newVal = it[key];
                    if (Array.isArray(newVal)) {
                        removeFromArray(it[key], ids, keyArray);
                    }
                });
            }
        });
    if (indexes.length) {
        if (indexes.length > 1)
            throw 'found multiple possible objects for the same key combination'
            arr.splice(indexes[0], 1);
    }
}

function compareArray(a1, a2, keyArray) {

    a2.forEach(function (it2) {
        var it1s = a1.filter(function (it) {
                return sameKeys(it2, it, keyArray);
            });
        var it1;
        if (!it1s.length) {
            it1 = clone(it2);
            a1.push(it1);
        } else {
            if (it1s.length > 1)
                throw 'found multiple possible objects for the same key combination'
                it1 = it1s[0];
            extend(it1, it2, keyArray);
        }
        if (it2.removedIds) {
            it2.removedIds.forEach(function (ids) {
                removeFromArray(a1, ids, keyArray);
            });
        }
    });

}
function compareArray(originalArray, destinationArray, propertyArray) {
            var newItem = new Array(), processedItem = new Array();
            for (var i = 0; i < originalArray.length; i++) {
                var sourceElement = originalArray[i];

                for (var j = 0; j < destinationArray.length; j++) {
                    var destinationElement = destinationArray[j];
                    var isUpdated = false;

                    if (sourceElement.constructor === Array) {
                        compareArray(sourceElement, destinationElement, propertyArray);
                    } else {
                        /* loop the property name to validate */

                        propertyArray.map(function(property) {
                            if (sourceElement[property]) {
                                if (sourceElement[property] === destinationElement[property]) {
                                    originalArray[i] = _.clone(destinationElement);
                                    isUpdated = true;
                                    return;
                                } else {
                                    var isAvailable = _.find(newItem, function(item) {
                                        return item[property] === destinationElement[property];
                                    });
                                    if (!isAvailable) {
                                        var isAlreadyProcessed = _.find(processedItem, function(item) {
                                            return item[property] === destinationElement[property];
                                        });
                                        if(!isAlreadyProcessed){
                                            newItem.push(destinationElement);
                                        }
                                    }
                                }
                            }
                        });
                    }
                    if (isUpdated === true) {
                        break;
                    }
                }
                processedItem.push(sourceElement);
            }
                newItem.map(function(item) {
                    originalArray.push(item);
                });

                return originalArray;
        }