2013-06-12 3 views
2

J'ai un tableau avec plusieurs objets de catégorie, chacun ayant une propriété items contenant un tableau d'objets éléments. Je veux mapper chaque élément de chaque catégorie à un objet [] avec des objets qui ont la valeur et l'étiquette des propriétés. Pour une raison quelconque, je ne peux pas effectuer la concaténation.Concaténer le tableau imbriqué après le mappage

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 [] 

Résultat attendu

[{ 
    label: "Item1", 
    value: "1" 
}, 
{ 
    label: "Item2", 
    value: "2" 
},{ 
    label: "Item3", 
    value: "3" 
},{ 
    label: "Item4", 
    value: "4" 
} 

Je me sens comme si je manque quelque chose très basique. J'ai enregistré le résultat de la fonction $.map et il semble retourner un []. Quelqu'un peut-il comprendre le problème?

jsFiddle:http://jsfiddle.net/vymJv/

+0

S'il vous plaît ne pas tenir compte. Je devais attribuer des éléments le résultat de la concat() –

Répondre

5

La méthode concat() est utilisée pour joindre deux ou plusieurs réseaux.

Cette méthode ne modifie pas les tableaux existants, mais renvoie un nouveau tableau contenant les valeurs des tableaux joints.

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

Merci pour la réponse, je me suis rendu compte peu de temps après que j'ai posté. Je suppose que j'avais besoin de l'exposer. Je vais accepter dans quelques-uns. –

10

Une autre méthode utilisant Javascript droite:

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

Sortie: x = [{label: "Item1", value: 1}, {label: "Item2", value: 2}, …]

2

Nous pourrions étendre le prototype de tableau en créant concatAll qui concaténer tous vos tableaux par ite évaluation sur chaque sous-tableau, en jetant chaque valeur dans un nouveau tableau.

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

Ensuite, nous pouvons obtenir le résultat souhaité avec les éléments suivants:

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

Nous obtenons les éléments en traduisant chaque catégorie dans un tableau d'éléments. Parce que nous avons deux catégories, nous finirons avec deux tableaux d'éléments. En appliquant concatAll sur le résultat final, nous aplatissons ces deux tableaux d'éléments et obtenons la sortie désirée.

0

Ce morceau de code permet de résoudre votre tâche en utilisant une approche de programmation fonctionnelle:

var items = [].concat.apply([], categories.map(cat => 
    cat.items.map(elem => ({ value:elem.itemId, label:elem.name }))) 
) 

Explication: Function.prototype.apply() a la syntaxe fun.apply(thisArg, [argsArray]) et nous permet de fournir des paramètres à une fonction dans un tableau. Array.prototype.concat() combine une quantité arbitraire de paramètres dans un tableau. Si nous écrivons maintenant Array.prototype.concat.apply([], [category1Items, ..., categoryNItems]), il est égal à [].concat(category1Items, ..., categoryNItems), qui concatène tous les paramètres ensemble. Vous pouvez également remplacer Array.prototype.concat par [].concat pour le garder plus court. Sinon, nous utilisons simplement le mapping standard pour faire le travail.

Vous pouvez également diviser le code à part un peu plus de clarté:

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