2016-02-26 118 views
0

我有以下几点:如何在Javascript中合并和过滤两个对象数组?

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

欢迎来到Stack Overflow!请[参观],环顾四周,并通读[帮助],特别是[*我如何提出一个好问题?](/帮助/如何问)和[*什么类型的我应该避免提问?*](/ help/dont-ask)你卡在哪里?在SO上的文化是,你至少应该尝试一下,然后如果遇到这样的问题,请展示尝试并描述问题。 –

+0

基本上,你需要做的就是循环'cars'并在所有者中找到与'ownerid'匹配的条目,然后构建新的对象。看看[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)以及阵列的所有可用函数,你应该可以做到这一点。由于您将一个数组(“汽车”)映射到一个新数组,所以'map'函数可能是一个很好的开始。然后再看'find'查找'owners'中的元素。将所有者转换为以id为单位的字典可能更有效。 –

回答

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

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

我不认为这是最好的方法:你将拥有owners.length * cars.length迭代。例如:如果所有者拥有20件物品和汽车,则代码将重复440次。 –

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

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); 
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 
    }; 
}); 
相关问题