【问题标题】:How to merge and filter two arrays of objects in Javascript? [closed]如何在Javascript中合并和过滤两个对象数组? [关闭]
【发布时间】:2016-02-26 14:22:21
【问题描述】:

我有以下几点:

var owners = [{
  "ownerid": "11",
  "name": "jane",
  "sex": "female"
}, {
  "ownerid": "22",
  "name": "mike",
  "sex": "male"
}, {
  "ownerid": "33",
  "name": "alex",
  "sex": "male"
}];

var cars = [{
  "ownerid": "11",
  "make": "ford",
  "model": "mustang"
}, {
  "ownerid": "11",
  "make": "honda",
  "model": "civic"
}, {
  "ownerid": "33",
  "make": "toyota",
  "model": "corolla"
}];

我想结束这个

var mergedandfiltered = [{
  "name": "jane",
  "sex": "female",
  "make": "ford",
  "model": "mustang"
}, {
  "name": "jane",
  "sex": "female",
  "make": "honda",
  "model": "civic"
}, {
  "name": "alex",
  "sex": "male",
  "make": "toyota",
  "model": "corolla"
}];

我们的想法是合并和过滤结果,这样我就有了车主、车主财产以及他们拥有的汽车和汽车财产的列表。迈克没有任何汽车,因此没有显示在结果中。 “ownerid”是通用链接,但我不需要它显示在结果中。

请首选纯 JS 解决方案!

【问题讨论】:

  • 欢迎来到 Stack Overflow!请拿起tour,环顾四周,并通读help center,尤其是How do I ask a good question?What types of questions should I avoid asking? 你在哪里卡住了? SO 的文化是您至少应该尝试一下,然后如果您在这样做时遇到问题,请展示尝试并描述问题。
  • 基本上,您需要做的就是遍历cars 并在所有者中找到与ownerid 匹配的条目,然后构建新对象。看看MDN 和所有可用的数组函数,你应该可以做到。 map 函数可能是一个很好的起点,因为您将一个数组(cars)映射到一个新数组。然后还要查看find 以查找owners 中的元素。将所有者转换为以 id 为键的字典可能更有效。

标签: javascript arrays filter merge


【解决方案1】:

为了提高效率,我们首先将用户列表转换为字典,使用所有者作为键。我们可以使用Array.protoype.reduce 来做到这一点:

var ownerDict = owners.reduce(function(p, c) {
  p[c.ownerid] = c;
  return p;
}, {});

这会给你一个看起来像这样的对象:

{
    "11": {
        "ownerid": "11",
        "name": "jane",
        "sex": "female"
    },
    "22": {
        "ownerid": "22",
        "name": "mike",
        "sex": "male"
    },
    "33": {
        "ownerid": "33",
        "name": "alex",
        "sex": "male"
    }
}

我们这样做的原因是因为现在我们可以查找用户,例如:

var owner = ownerDict[11];

这将把对象还给你:

{
    "ownerid": "11",
    "name": "jane",
    "sex": "female"
}

然后查找是O(1)。如果您必须实际搜索数组以找到它,假设它尚未排序,您的搜索将是 O(n)(如果它已排序,您的示例数据实际上似乎是,它只是稍微好一点 - 你可以 使用二叉树搜索 O(log(n)),但仍然比 O(1) 慢,而且代码更复杂。)

现在有了那个字典,我们现在可以使用Array.prototype.map 将我们的cars 数组转换成你想要的样子:

var mergedandfiltered = cars.map(function(c) {
  var owner = ownerDict[c.ownerid];
  return {
    name: owner.name,
    sex: owner.sex,
    make: c.make,
    model: c.model
  };
});

【讨论】:

    【解决方案2】:

    首先构建一个对象供车主参考,然后遍历汽车,并组合一个新对象。

    var owners = [{ "ownerid": "11", "name": "jane", "sex": "female" }, { "ownerid": "22", "name": "mike", "sex": "male" }, { "ownerid": "33", "name": "alex", "sex": "male" }],
        cars = [{ "ownerid": "11", "make": "ford", "model": "mustang" }, { "ownerid": "11", "make": "honda", "model": "civic" }, { "ownerid": "33", "make": "toyota", "model": "corolla" }],
        obj = {},
        result;
    
    owners.forEach(function (a) {
        obj[a.ownerid] = a;
    });
    
    result = cars.map(function (a) {
        return {
            name: obj[a.ownerid].name,
            sex: obj[a.ownerid].sex,
            make: a.make,
            model: a.model
        };
    });
    
    document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

    【讨论】:

      【解决方案3】:
      var owners = [{"ownerid":"11", "name":"jane", "sex":"female"}, {"ownerid":"22", "name":"mike", "sex":"male"}, {"ownerid":"33", "name":"alex", "sex":"male"}];
      
      var cars = [{"ownerid":"11", "make":"ford", "model":"mustang"}, {"ownerid":"11", "make":"honda", "model":"civic"}, {"ownerid":"33", "make":"toyota", "model":"corolla"} ];
      
      var mergedandfiltered = [];
      for(var i = 0; i < owners.length; i++){
        for(var j = 0; j < cars.length; j++){
          if(owners[i]['ownerid'] == cars[j]['ownerid']){
              mergedandfiltered.push({"name":owners[i]['name'],"sex":owners[i]['sex'],"make":cars[j]['make'],"model":cars[j]['model']});
          }        
        }  
      }
      

      【讨论】:

      • 我认为这不是最好的方法:您将拥有 owner.length * cars.length 迭代。示例:如果所有者有 20 件物品和汽车,则为 22,代码将迭代 440 次。
      【解决方案4】:
      var mergedandfiltered = [];
      for (var i = 0; i < owners.length; i++) {
          var oID = owners[i].ownerid;
          for (var j = 0; j < cars.length; j++) {
            var mitem = {};
            cID = cars[j].ownerid;
            if (oID==cID) {
              mitem.name = owners[i].name;
              mitem.sex = owners[i].sex;
              mitem.make = cars[j].make;
              mitem.model = cars[j].model;
              mergedandfiltered.push(mitem);
            }
          }
      }
      

      【讨论】:

        【解决方案5】:
        var owners = [ {
                "ownerid" : "11",
            "name" : "jane",
            "sex" : "female"
        }, {
            "ownerid" : "22",
            "name" : "mike",
            "sex" : "male"
        }, {
            "ownerid" : "33",
            "name" : "alex",
            "sex" : "male"
        } ];
        
        var cars = [ {
            "ownerid" : "11",
            "make" : "ford",
            "model" : "mustang"
        }, {
            "ownerid" : "11",
            "make" : "honda",
            "model" : "civic"
        }, {
            "ownerid" : "33",
            "make" : "toyota",
            "model" : "corolla"
        } ];
        
        var merge = function(array, array2, filter) {
            var result = [];
            for ( var i in array) {
                for (var j in array2) {
                    var filtered = filter(array[i],array2[j]);
                    if (filtered != null){
                        result.push(filtered);
                    }
        
                }
            }
            return result;
        };
        var result = merge(owners,cars,function(owner,car){
            if (owner.ownerid == car.ownerid){
                return {
                    name : owner.name,
                    model : car.model
                };
            }
            return null;
        });
        console.log('array',result);
        

        【讨论】:

          【解决方案6】:

          您可以将您的所有者数组转换为“哈希”(使用所有者作为键),然后根据汽车数组中的 ownerid 获取其属性。

          var hashowners = [];
          owners.forEach(function(o) {
             hashowners[o.ownerid] = {"name": o.name, "sex": o.sex};
          });
          
          var finalcars = cars.map( function(car) {
              car.name = hashowners[car.ownerid].name;
              car.sex = hashowners[car.ownerid].sex;
              delete car.ownerid;
              return car;
          });
          
          console.log(finalcars)
          

          小提琴:https://jsfiddle.net/61fb13n8/

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-07-13
            • 1970-01-01
            • 2019-06-14
            • 2019-09-26
            • 1970-01-01
            • 2016-12-15
            • 2020-07-04
            • 2022-01-23
            相关资源
            最近更新 更多