Imaginez que j'ai une structure de matrice imbriquée.
var nested = [ [1], [2], [3] ];
Utilisation nderscore.js , comment ferais-je produire un tableau aplatie?
En C #, vous utiliseriez Enumerable.SelectMany
comme ceci:
var flattened = nested.SelectMany(item => item);
Notez que la Lambda dans ce cas sélectionne directement l'élément imbriqué, mais cela aurait pu être une expression arbitraire.
À JQuery, il est possible de simplement utiliser:
var flattened = $.map(nested, function(item) { return item; });
Cependant, cette approche ne fonctionne pas avec la fonction de sous-traitance carte .
Alors, comment puis-je obtenir le tableau aplatie [1, 2, 3]
utiliser des sous-traitants.js?
var nested = [ [1], [2], [3] ];
var flattened = _.flatten(nested);
Heres A violon
Si vous avez une matrice légèrement plus compliquée, dites-en une venant de JSON, vous pouvez également profiter de la méthode PLUCK Méthode, extrayant la propriété spécifique qui vous intéresse, similaire à parents.SelectMany(parent => parent.Items);
// underscore version
var allitems = _.flatten(_.pluck(parents, 'items'));
allitems
est maintenant le tableau de tous les subitems des parents, [a,b,c,d]
.
Et a jsfiddle montrant la même chose.
Ou, si vous utilisez Lodash, vous pouvez faire la même chose en utilisant la fonction _. Platmap Fonction disponible depuis la version 4. Crédiez à Noel pour le pointer dans les commentaires.
var parents = [
{ name: 'hello', items: ['a', 'b'] },
{ name: 'world', items: ['c', 'd'] }
];
// version 1 of lodash, straight up
var allitems = _.flatMap(parents, 'items');
logIt('straight', allitems);
// or by wrapping the collection first
var allitems = _(parents)
.flatMap('items')
.value();
logIt('wrapped', allitems);
// this basically does _(parents).map('items').flatten().value();
function logIt(wat, value) {
console.log(wat, value)
}
<script src="https://cdn.jsdelivr.net/lodash/4.16.6/lodash.min.js"></script>
<pre id="result"></pre>
Si vous souhaitez faire plus de choses et que vous ne voulez pas de chaîner des opérateurs, vous pouvez utiliser la fonction flow
fonction pour obtenir le même effet. Ceci est utile si vous utilisez des documents dotés et importaient chaque opérateur individuellement, car vous pouvez ensuite optimiser votre charge utile finale.
const parents = [
{ name: 'hello', items: ['a', 'b'] },
{ name: 'world', items: ['c', 'd'] }
];
logIt('original', parents);
const result = _.flow(
(collection) => _.flatMap(collection, (item) => item.items),
(flattened) => flattened.filter((item) => item !== 'd')
)(parents);
logIt('result without "d"', result);
function logIt(wat, value) {
console.log(wat, value);
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<pre id="result"></pre>
Nous pouvons également faire Solution de Patrick dans un mixin de sorte qu'il devienne charabitable:
_.mixin({
selectMany: function(collection, iteratee=_.identity) {
return _.flatten(_.map(collection, iteratee));
}
});
Exemples:
let sample = [{a:[1,2],b:'x'},{a:[3,4],b:'y'}];
console.log(_.selectMany(sample, 'a')); // [ 1, 2, 3, 4 ]
console.log(_.chain(sample).selectMany(o => o.a).filter(a => a % 2 === 0).map(a => a * 3).value()); // [ 6, 12 ]
Je ne pouvais trouver aucune méthode dans Lodash qui fonctionne tout à fait comme SelectMany
, donc j'ai créé un en utilisant Pure JS:
Array.prototype.selectMany = function(fn) {
return Array.prototype.concat(...this.map(fn));
};
Boom.
> console.log([{a:[1,2],b:'x'},{a:[3,4],b:'y'}].selectMany(o => o.a));
[ 1, 2, 3, 4 ]