如何在Javascript中合并和过滤两个对象数组?

时间:2016-02-26 14:22:22

标签: javascript arrays filter merge

我有以下内容:

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解决方案!

6 个答案:

答案 0 :(得分: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>');
&#13;
&#13;
&#13;

答案 1 :(得分:1)

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']});
    }        
  }  
}

答案 2 :(得分: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
  };
});

答案 3 :(得分:0)

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);
      }
    }
}

答案 4 :(得分:0)

您可以将所有者数组转换为“哈希”(使用所有者作为键),然后根据来自汽车阵列的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/

答案 5 :(得分:0)

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);