根据条件将数组的元素替换为另一个数组的元素
Posted
技术标签:
【中文标题】根据条件将数组的元素替换为另一个数组的元素【英文标题】:Replace elements of an array with elements of another array based on a condition 【发布时间】:2020-03-19 05:48:51 【问题描述】:我有 2 个数组,
let array1 = ["1", "2", "3"]
let array2 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3", "name": "c", "id" : "4"]
当 array1 元素和 array2 @987654323 时,我想用 array2 的元素替换 array1 的内容@ 元素的值匹配。 结果应该是这样的:
array1 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3"]
我知道我可以在单独的数组中得到结果,但我想替换 array1 的内容而不必创建新数组。
我试过这个:
array1.splice(0, Infinity, ...array2)
基于对类似问题here的回答
这会导致:
array1 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3", "name": "c", "id" : "4"]
我尝试了不同的方法来向该语句添加条件,但失败了。有没有办法在上面的拼接方法中添加条件?或者如果有更好的方法来实现它,请提出建议。
【问题讨论】:
【参考方案1】:我们可以使用keyed collection - Map按键获取物品。
const array1 = ["1", "2", "3"]
const array2 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3", "name": "c", "id" : "4"]
const array2Map = new Map(array2.map(o=> [o.id, o]));
const result = array1.map(o => (
...array2Map.get(o)
));
console.log(result);
此外,您可以使用filter
和some
方法来达到预期的效果:
let array1 = ["1", "2", "3"]
let array2 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3", "name": "c", "id" : "4"]
array1 = array2.filter(f=> array1.some(s=> s == f.id));
console.log(array1);
另一种方式,但更冗长且不是最佳方式:
let array1 = ["1", "2", "3"]
let array2 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3", "name": "c", "id" : "4"]
array1 = array1.map(a =>
let obj = array2.find(a2=> a2.id == a);
if (obj) return obj;
return a;
)
console.log(array1);
【讨论】:
【参考方案2】:let array1 = ["1", "2", "3"]
let array2 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3", "name": "c", "id" : "4"]
array1 = array2.filter(f=> array1.find(s=> s == f.id));
console.log(array1);
/**outPut :[
"name": "a",
"id": "1"
,
"name": "b",
"id": "2"
,
"name": "c",
"id": "3"
]**/
【讨论】:
【参考方案3】:看起来Array.filter
可以完成这项工作?
let array1 = ["1", "2", "3"];
array1 = [
"name": "a", "id" : "1",
"name": "b", "id" : "2",
"name": "c", "id" : "3",
"name": "c", "id" : "4"
].filter(v => array1.includes(v.id));
// using Array.indexOf (IE >= 9, nodejs all versions),
let array2 = ["1", "2", "3"];
array2 = [
"name": "a", "id" : "1",
"name": "b", "id" : "2",
"name": "c", "id" : "3",
"name": "c", "id" : "4"
].filter(v => array2.indexOf(v.id) > -1);
console.log(array1);
console.log(array2);
【讨论】:
这可行,但 Internet Explorer 不支持includes
,根据this,也不支持低于 6.0.0 的 node.js 版本。
如果浏览器(甚至 nodejs)的兼容性真的是个问题,你可以使用 polyfill (developer.mozilla.org/nl/docs/Web/javascript/Reference/…)
@hushie 你可以在问题中提到兼容性要求
@Kooilnc 我应该有,我错过了。【参考方案4】:
您还可以在 array1 中搜索 array2 id,然后将 array1 的索引替换为匹配的 array2 索引。
let array1 = ["1", "2", "3"]
let array2 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3", "name": "c", "id" : "4"]
array2.forEach(function(e)
if(array1.indexOf(e["id"]) != -1)
array1[array1.indexOf(e["id"])] = e
)
console.log(array1)
编辑:我尝试了一种不同的方法,将 array1 中的每个值与过滤器中的 array2 id 值进行比较,我认为这不是一个更清洁的解决方案,但我尝试了:
let array1 = ["1", "2", "3"]
let array2 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3", "name": "c", "id" : "4"]
array1 = array1.map(num =>
return array2.filter(dict =>
if(dict["id"] == num) return dict
)[0]
)
console.log(array1)
如果你可以使用 lodash,那就很短了:
let array1 = ["1", "2", "3"]
let array2 = ["name": "a", "id" : "1", "name": "b", "id" : "2", "name": "c", "id" : "3", "name": "c", "id" : "4"]
array1 = _.map(array1, function(o)return _.find(array2, id: o))
console.log(array1)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
【讨论】:
必须有更短的方法来实现这一点,而不必遍历数组? 我用另外两种方法更新了答案,以使它们中的任何一种都符合您的要求。下面@StepUp 发送的答案看起来像您正在寻找的答案。以上是关于根据条件将数组的元素替换为另一个数组的元素的主要内容,如果未能解决你的问题,请参考以下文章
BigQuery LEFT JOIN 一个表并根据条件过滤其数组元素
根据同一数组中另一个元素满足的条件更新 mongo 集合中数组的元素