2013-06-12 75 views
2

我有一个数组,其中有几个类别对象,每个对象都有一个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

请忽略。我需要分配项目的结果concat() –

回答

5

的concat()方法被用于连接两个或更多个阵列。

此方法不会更改现有数组,但返回包含连接数组值的新数组 。

http://jsfiddle.net/vymJv/1/

for(var i = 0; i < categories.length; i++){ 

items = items.concat($.map(categories[i].items,function(elem){ 
     return {value:elem.itemId, label:elem.name}; 
    })); 
} 
+0

感谢您的答案,我发布后不久我意识到这一点。我想我需要把它摆平。我会接受几个。 –

10

使用直的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}, …]

2

我们可以通过创建concatAll将串联所有的扩展阵列原型你的数组通过ite评估每个子阵列,将每个值转储到新阵列中。每个类别转换成项目的数组

let items = categories.map(function(category) { 
    return category.items.map(function(item) { 
    return {label: item.name, value: item.itemId}; 
    }); 
}).concatAll(); 

我们拿到的项目:

Array.prototype.concatAll = function() { 
    var results = []; 
    this.forEach(function(subArray) { 
    subArray.forEach(function(subArrayValue) { 
     results.push(subArrayValue); 
    }); 
    }); 
    return results; 
}; 

然后,我们可以用下面的获得所需的结果。因为我们有两个类别,我们最终会得到两个项目数组。通过对最终结果应用concatAll,我们将这两个项目数组进行平展并获得所需的输出。

0

这段代码解决了使用功能的编程方法你的任务:

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),它将所有参数连接在一起。您也可以用[].concat代替Array.prototype.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));