我有一个包含多个类别对象的数组,每个类别对象都有一个包含项目对象数组的items
属性。我想将每个类别中的每个项目映射到具有属性值和标签的对象[]。出于某种原因,我无法执行连接。
var categories = [{
name: "category1",
items: [{
itemId: 1,
name: "Item1"
}, {
itemId: 2,
name: "Item2"
}]
}, {
name: "category2",
items: [{
itemId: 3,
name: "Item3"
}, {
itemId: 4,
name: "Item4"
}]
}];
var items = [];
for(var i = 0; i < categories.length; i++){
items.concat($.map(categories[i].items,function(elem){
return {value:elem.itemId, label:elem.name};
}));
}
console.log(items); //prints []
预期结果
[{
label: "Item1",
value: "1"
},
{
label: "Item2",
value: "2"
},{
label: "Item3",
value: "3"
},{
label: "Item4",
value: "4"
}
我觉得我错过了一些非常基本的东西。我记录了$.map
函数的结果,似乎返回了[]
。有人能解决这个问题吗?
JSFiddle: http://jsfiddle.net/vymJv/
答案 0 :(得分:19)
使用直接Javascript的另一种方法:
var x = categories.map(function(val) {
return val.items;
}).reduce(function(pre, cur) {
return pre.concat(cur);
}).map(function(e,i) {
return {label:e.name,value:e.itemId};
});
输出:x = [{label: "Item1", value: 1}, {label: "Item2", value: 2}, …]
答案 1 :(得分:6)
concat()方法用于连接两个或多个数组。
此方法不会更改现有数组,但会返回新数组 array,包含连接数组的值。
for(var i = 0; i < categories.length; i++){
items = items.concat($.map(categories[i].items, function(elem) {
return {value: elem.itemId, label: elem.name};
}));
}
答案 2 :(得分:3)
我们可以通过创建 concatAll 来扩展数组原型,它将通过迭代每个子数组来连接所有数组,将每个值转储到一个新数组中。
Array.prototype.concatAll = function() {
var results = [];
this.forEach(function(subArray) {
subArray.forEach(function(subArrayValue) {
results.push(subArrayValue);
});
});
return results;
};
然后,我们可以通过以下方式获得所需的结果:
let items = categories.map(function(category) {
return category.items.map(function(item) {
return {label: item.name, value: item.itemId};
});
}).concatAll();
我们通过将每个类别转换为一系列项目来获取项目。因为我们有两个类别,我们最终将得到两个项目数组。通过对最终结果应用 concatAll ,我们将这两个项目数组展平并获得所需的输出。
答案 3 :(得分:2)
这段代码使用函数式编程方法解决了您的任务:
var items = [].concat.apply([], categories.map(cat =>
cat.items.map(elem => ({ value:elem.itemId, label:elem.name })))
)
说明:Function.prototype.apply()具有语法fun.apply(thisArg, [argsArray])
,并允许我们为数组中的函数提供参数。 Array.prototype.concat()将任意数量的参数组合到一个数组中。如果我们现在写Array.prototype.concat.apply([], [category1Items, ..., categoryNItems])
,它实际上等于[].concat(category1Items, ..., categoryNItems)
,它将所有参数连接在一起。您也可以将Array.prototype.concat
替换为[].concat
以缩短时间。否则,我们只使用标准映射来完成工作。
为清晰起见,您还可以将代码分开一点:
function getItem(elem){
return {value:elem.itemId, label:elem.name};
}
function getCategoryItems(cat) {
return cat.items.map(getItem);
}
function flatten(arr) {
return Array.prototype.concat.apply([], arr);
}
var items = flatten(categories.map(getCategoryItems));
答案 4 :(得分:1)
const items = categories
.map(category => category.items)
.reduce((prev, current) => [...prev, ...current])
.map((e, i) => ({ label: e.name, value: e.itemId }));
答案 5 :(得分:1)
更新为flatMap
(与 IE 不兼容)
categories.flatMap((categories) => categories.items)
flatMap() 方法返回一个新数组,该数组通过对数组的每个元素应用给定的回调函数,然后将结果展平一级而形成。