如何简化基于属性组合两个数组的es6函数?
How do I simplify my es6 function that combines two arrays based on properties?
我有两个数组,一个现有的集合和一个新的数组。我想用下面的方式将两者结合起来:
- 从现有对话中的所有元素开始
- 对于新数组中的每个项目,如果具有相同
id
的元素在现有数组中不存在,则我们将添加它。 - 如果确实存在具有相同
id
的产品,则只有当新产品的updated
属性值大于现有产品的updated
属性值时,我们才替换现有产品。 - 如果小于等于,则忽略新元素。
不能修改传入的数组,必须返回组合后的数组。
function combineConversations(newConversations, existingConversations) {
const combined = [...existingConversations];
newConversations.forEach(conversation => {
const existingConversationIndex = indexOfObject(combined, conversation.id , 'id');
if (existingConversationIndex && conversation.updated > combined[existingConversationIndex].updated) {
combined[existingConversationIndex] = conversation;
} else {
combined.push(conversation);
}
});
return combined;
}
我想知道一个完整的功能方法来做这件事。有吗?
是的,你可以用这样的函数式方法来做:
var oldChat = [
{id: 1, updated: 1985, data: "coucou"},
{id: 2, updated: 1995, data: "au revoir"},
{id: 3, updated: 2003, data: "bonjour"}
];
var newChat = [
{id: 1, updated: 1986, data: "coucou"},
{id: 2, updated: 2004, data: "bye"},
{id: 3, updated: 2001, data: "bonjour"},
{id: 4, updated: 2008, data: "vive le sport"}
];
var result = (oldChat, newChat) => newChat.concat(oldChat).sort((a,b) => a.id-b.id).filter((item, index, arr) => index < arr.length - 1 ? item.id !== arr[index+1].id : true);
console.log(result(oldChat, newChat)); //[ { id: 1, updated: 1986, data: 'coucou' },
//{ id: 2, updated: 2004, data: 'bye' },
//{ id: 3, updated: 2003, data: 'bonjour' },
//{ id: 4, updated: 2008, data: 'vive le sport' } ]
编辑:我合并了新旧数组,并对它们进行了排序,以获得具有相同id的相邻元素,然后过滤以保留那些具有唯一id或最新更新的元素
这里有另一种方法来解决你的问题(我使用了@kevinternet的例子,希望他不介意):
var oldChat = [
{id: 1, updated: 1985, data: "coucou"},
{id: 2, updated: 1995, data: "au revoir"},
{id: 3, updated: 2003, data: "bonjour"}
];
var newChat = [
{id: 1, updated: 1986, data: "coucou"},
{id: 2, updated: 2004, data: "bye"},
{id: 3, updated: 2001, data: "bonjour"},
{id: 4, updated: 2008, data: "vive le sport"}
];
var intersect = oldChat.reduce((memo, val) => memo.concat(newChat.find(v => val.id === v.id && val.updated < v.updated) || val), []);
var diff = newChat.filter(x => !oldChat.some(y => y.id === x.id));
console.log(intersect.concat(diff));
思路是:
- 使两个数组相交。这是一个特殊的交集:如果比较的元素有相同的ID,我们必须取更新的多,所以
find
有一个特殊的条件,新元素必须比旧元素更新的多,否则,我们没有找到正确的替换。 - 我们必须处理
oldChat
和newChat
之间不常见的元素。由于我们执行了从oldChat
到newChat
的特殊交集(这保证了oldChat
中的所有对象将在新对象中),我们执行了从newChat
到oldChat
的差异。 - 将特殊路口与差值连接,以获得所需的结果。
希望能有所帮助。
我明白了!
function combineConversations(myArr) {
return myArr.filter((item1, pos, arr) =>
arr.map(item2 => item1.id === item2.id && item1.updated === item2.updated).indexOf(true) === pos &&
arr.every(item2 => !(item1 !== item2 && item1.id === item2.id && item1.updated < item2.updated))
);
}
combineConversations([...newChat, ...oldChat]);
var oldChat = [
{id: 1, updated: 1985, data: "coucou"},
{id: 2, updated: 1995, data: "au revoir"},
{id: 3, updated: 2003, data: "bonjour"},
{id: 4, updated: 2016, data: "hallo"},
];
var newChat = [
{id: 1, updated: 1986, data: "coucou"},
{id: 2, updated: 2004, data: "bye"},
{id: 3, updated: 2001, data: "bonjour"},
{id: 5, updated: 2008, data: "vive le sport"}
];
var expected = [
{id: 1, updated: 1986, data: "coucou"},
{id: 2, updated: 2004, data: "bye"},
{id: 3, updated: 2003, data: "bonjour"},
{id: 4, updated: 2016, data: "hallo"},
{id: 5, updated: 2008, data: "vive le sport"}
];
谢谢@ kevinternet的回答。你让我走上了正确的道路!
相关文章:
- 如何使用 node.js 比较两个 json 数组
- 用每小时的差值填充数组/列表-从下拉列表中给定两个时间值
- 访问$.ajax()函数中的两个不同数组
- 正在更新mongod中两个对象内部的数组
- 如何使用javascript合并两个对象数组
- 比较包含多个值对的两个JavaScript数组
- jQuery对象从html表中查询为两个一维数组,用于Chartist图表
- 检查来自不同数组的两个元素的一个属性是否相等
- 如何在javascript中合并两个对象数组
- JavaScript - 合并两个对象数组并根据属性值删除重复数据
- 效率:整数数组的一个子集中两个项之间的最大差值
- 将两个值组合成extjs 4.1的形式
- 如何将中的两个geoJSON功能集合添加到两个层组中
- 在 JQuery 验证中验证多个“数组命名”文件输入和下拉列表
- 在一个区间之间生成两个随机数组
- 使用两个捕获组和JavaScript的replace()函数
- 通过找到两个重复组之一的正则表达式组
- 从Javascript中的两个子数组中获取随机结果
- 如何在一个可选的非捕获组中创建两个捕获组
- paper.js:获取两个层/组的原始像素数据