【问题标题】: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"}]

我尝试了不同的方法来向该语句添加条件,但失败了。有没有办法在上面的拼接方法中添加条件?或者如果有更好的方法来实现它,请提出建议。

【问题讨论】:

    标签: javascript arrays


    【解决方案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);

    此外,您可以使用filtersome 方法来达到预期的效果:

    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 发送的答案看起来像您正在寻找的答案。
        猜你喜欢
        • 2014-11-07
        • 2021-12-12
        • 1970-01-01
        • 2015-08-30
        • 2013-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多