JavaScript - 合并两个对象数组并根据属性值进行重复数据删除

时间:2016-05-05 18:29:31

标签: javascript arrays object underscore.js

我希望更新(替换)我的数组中的对象与另一个数组中的对象。每个对象具有相同的结构。 e.g。

var origArr = [
  {name: 'Trump', isRunning: true},
  {name: 'Cruz', isRunning: true},
  {name: 'Kasich', isRunning: true}
];
var updatingArr = [
  {name: 'Cruz', isRunning: false},
  {name: 'Kasich', isRunning: false}
];
// desired result:
NEWArr = [
  {name: 'Trump', isRunning: true},
  {name: 'Cruz', isRunning: false},
  {name: 'Kasich', isRunning: false}
];

我尝试过concat()&下划线的_.uniq功能,但它总是转储较新的对象&基本上返回原始数组。

有没有办法用origArr中的对象覆盖(替换)updatingArr - 匹配name属性?

11 个答案:

答案 0 :(得分:6)

我来到这里正是为了寻找这个,看到了@Gruff Bunny的技巧,并想知道是否' lodash'即使是“强调”也不是一个优越的选择?

瞧瞧:

let result = _.unionBy(updatingArr, origArr, 'name');

答案 1 :(得分:3)

使用双循环和拼接,你可以这样做:

for(var i = 0, l = origArr.length; i < l; i++) {
    for(var j = 0, ll = updatingArr.length; j < ll; j++) {
        if(origArr[i].name === updatingArr[j].name) {
            origArr.splice(i, 1, updatingArr[j]);
            break;
        }
    }
}

示例here

答案 2 :(得分:2)

您可以将Array#mapArray#reduce

结合使用

var origArr = [{ name: 'Trump', isRunning: true }, { name: 'Cruz', isRunning: true }, { name: 'Kasich', isRunning: true }],
    updatingArr = [{ name: 'Cruz', isRunning: false }, { name: 'Kasich', isRunning: false }],
    NEWArr = origArr.map(function (a) {
        return this[a.name] || a;
    }, updatingArr.reduce(function (r, a) {
        r[a.name] = a;
        return r;
    }, Object.create(null)));

document.write('<pre>' + JSON.stringify(NEWArr, 0, 4) + '</pre>');

答案 3 :(得分:2)

您可以使用按名称提供索引的哈希值,并使用Object.assign进行更新。

var hash = origArr.reduce(function(hash, obj, index) {
  hash[obj.name] = index;
  return hash;
}, Object.create(null));
for(var obj of updatingArr) {
  Object.assign(origArr[hash[obj.name]], obj);
}

答案 4 :(得分:2)

你可以尝试一下。

var origArr = [
  {name: 'Trump', isRunning: true},
  {name: 'Cruz', isRunning: true},
  {name: 'Kasich', isRunning: true}
];
var updatingArr = [
  {name: 'Cruz', isRunning: false},
  {name: 'Kasich', isRunning: false}
];

var origLength = origArr.length;
var updatingLength = updatingArr.length;

//Traverse the original array and replace only if the second array also has the same value
for(i = origLength-1; i >= 0; i--) {
    for(j = updatingLength -1; j >= 0; j--) {
    if(origArr[i].name === updatingArr[j].name) {
        origArr[i] = updatingArr[j];
    }
  }
}

console.log(origArr);

答案 5 :(得分:2)

以下是使用下划线的解决方案:

var result = _.map(origArr, function(orig){
    return _.extend(orig, _.findWhere(updatingArr, {name: orig.name}));
});

答案 6 :(得分:1)

这将满足您的需求:

&#13;
&#13;
var origArr = [
  {name: 'Trump', isRunning: true},
  {name: 'Cruz', isRunning: true},
  {name: 'Kasich', isRunning: true}
];

var updatingArr = [
  {name: 'Cruz', isRunning: false},
  {name: 'Kasich', isRunning: false}
];

for (var i = 0; i < updatingArr.length; ++i) {
  var updateItem = updatingArr[i];
  for (var j = 0; j < origArr.length; ++j) {
    var origItem = origArr[j];
    if (origItem.name == updateItem.name) {
      origItem.isRunning = updateItem.isRunning;
      break;    
    }
  }
}

document.write('<pre>' + JSON.stringify(origArr, 0, 4) + '</pre>');
&#13;
&#13;
&#13;

答案 7 :(得分:1)

const origArr = [
  {name: 'Trump', isRunning: true},
  {name: 'Cruz', isRunning: true},
  {name: 'Kasich', isRunning: true}
];

const updatingArr = [
  {name: 'Cruz', isRunning: false},
  {name: 'Kasich', isRunning: false}
];

let hash = {};

for(let i of origArr.concat(updatingArr)) {
  if(!hash[i]) {
    hash[i.name] = i;
  }
}

let newArr = [];

for(let i in hash) {
  newArr.push(hash[i])
}

console.log(newArr);

答案 8 :(得分:0)

此版本可让您定义selector,该对象将对象定义为重复对象。

  • forEach遍历新数据
  • 如果两个选择器相等,则
  • findIndex返回索引>= 0。如果没有相等,则返回-1
  • 如果有重复项,我们将使用slice将其替换为新的。
  • 如果没有重复项,我们将其推入原始数组。

const origArr = [
  {name: 'Trump', isRunning: true},
  {name: 'Cruz', isRunning: true},
  {name: 'Kasich', isRunning: true}
];

const updatingArr = [
  {name: 'Cruz', isRunning: false},
  {name: 'Kasich', isRunning: false}
];

const mergeArrayOfObjects = (original, newdata, selector = 'key') => {
	newdata.forEach(dat => {
		const foundIndex = original.findIndex(ori => ori[selector] == dat[selector]);
		if (foundIndex >= 0) original.splice(foundIndex, 1, dat);
        else original.push(dat);
	});

	return original;
};

const result = mergeArrayOfObjects(origArr, updatingArr, "name")
console.log('RESULT -->', result)

答案 9 :(得分:0)

尝试使用ES-6 设置数据结构进行此方法: from time import sleep import time import datetime now = datetime.datetime.now() Start_Time = datetime.datetime.now() Str_time = Start_Time.strftime("%H:%M:%S") End_Time = '11:15:00' starttime=time.time() diff = 0 class sampleTest: @staticmethod def test(): list1 = ["Hello", "Hi", "Ola"] list2 = [5, 10, 7] for i in range(len(list1)): if (diff % list2[i] == 0): t = datetime.datetime.now().strftime('%H:%M:%S') print(f"{list1[i]} delay {list2[i]} & time is {t} ") if __name__ == '__main__': obj = sampleTest while Str_time < End_Time: obj.test() time.sleep(1); diff = int(time.time() - starttime) Str_time = datetime.datetime.now().strftime("%H:%M:%S") else: print("Time Is done")

答案 10 :(得分:0)

与@gevorg答案相同,但是如果找不到匹配项,您可能还希望向原始数组中添加一个新对象。

let combinedEvents = origEvents;
for(let i =0; i< newEvents.length; i++){
  let newEvent = newEvents[i];
  for(let j =0; j< origEvents.length; j++){
    let origEvent = origEvents[j];
    if(newEvent.events_id == origEvent.events_id){
      combinedEvents.splice(j,1, newEvent);
      break;
    } else if(j === origEvents.length - 1){
      combinedEvents.push(newEvent);
      break;
    }
  }
}