web-dev-qa-db-fra.com

Comment faire l'équivalent de LINQ SelectMany () juste en javascript

Malheureusement, je n'ai ni JQuery ni Underscore, seulement du javascript pur (compatible IE9).

Je veux l'équivalent de SelectMany () de la fonctionnalité LINQ.

// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);

Puis-je le faire?

MODIFIER:

Grâce aux réponses, j'ai obtenu ce travail:

var petOwners = 
[
    {
        Name: "Higa, Sidney", Pets: ["Scruffy", "Sam"]
    },
    {
        Name: "Ashkenazi, Ronen", Pets: ["Walker", "Sugar"]
    },
    {
        Name: "Price, Vernette", Pets: ["Scratches", "Diesel"]
    },
];

function property(key){return function(x){return x[key];}}
function flatten(a,b){return a.concat(b);}

var allPets = petOwners.map(property("Pets")).reduce(flatten,[]);

console.log(petOwners[0].Pets[0]);
console.log(allPets.length); // 6

var allPets2 = petOwners.map(function(p){ return p.Pets; }).reduce(function(a, b){ return a.concat(b); },[]); // all in one line

console.log(allPets2.length); // 6
61
toddmo

pour une sélection simple, vous pouvez utiliser la fonction de réduction de Array.
Disons que vous avez un tableau de tableaux de nombres:

var arr = [[1,2],[3, 4]];
arr.reduce(function(a, b){ return a.concat(b); });
=>  [1,2,3,4]

var arr = [{ name: "name1", phoneNumbers : [5551111, 5552222]},{ name: "name2",phoneNumbers : [5553333] }];
arr.map(function(p){ return p.phoneNumbers; })
   .reduce(function(a, b){ return a.concat(b); })
=>  [5551111, 5552222, 5553333]
89
Sagi

Sagi utilise correctement la méthode concat pour aplatir un tableau. Mais pour obtenir quelque chose de similaire à cet exemple, vous aurez également besoin d’une carte pour la partie sélectionnée https://msdn.Microsoft.com/library/bb534336 (v = vs.100) .aspx

/* arr is something like this from the example PetOwner[] petOwners = 
                    { new PetOwner { Name="Higa, Sidney", 
                          Pets = new List<string>{ "Scruffy", "Sam" } },
                      new PetOwner { Name="Ashkenazi, Ronen", 
                          Pets = new List<string>{ "Walker", "Sugar" } },
                      new PetOwner { Name="Price, Vernette", 
                          Pets = new List<string>{ "Scratches", "Diesel" } } }; */

function property(key){return function(x){return x[key];}}
function flatten(a,b){return a.concat(b);}

arr.map(property("pets")).reduce(flatten,[])
8
Fabio Beltramini

Pour ceux qui seront un peu plus tard, comprendre le javascript tout en souhaitant une méthode simple Typed SelectMany dans TypeScript:

function selectMany<TIn, TOut>(input: TIn[], selectListFn: (t: TIn) => TOut[]): TOut[] {
  return input.reduce((out, inx) => {
    out.Push(...selectListFn(inx));
    return out;
  }, new Array<TOut>());
}
8
Joel Harkes

Comme une option plus simple Array.prototype.flat ()

const data = [
{id: 1, name: 'Dummy Data1', details: [{id: 1, name: 'Dummy Data1 Details'}, {id: 1, name: 'Dummy Data1 Details2'}]},
{id: 1, name: 'Dummy Data2', details: [{id: 2, name: 'Dummy Data2 Details'}, {id: 1, name: 'Dummy Data2 Details2'}]},
{id: 1, name: 'Dummy Data3', details: [{id: 3, name: 'Dummy Data3 Details'}, {id: 1, name: 'Dummy Data3 Details2'}]},
]

const result = data.map(a => a.details).flat(1);
console.log(result)
5
Necip
// you can save this function in a common js file of your project
function selectMany(f){ 
    return function (acc,b) {
        return acc.concat(f(b))
    }
}

var ex1 = [{items:[1,2]},{items:[4,"asda"]}];
var ex2 = [[1,2,3],[4,5]]
var ex3 = []
var ex4 = [{nodes:["1","v"]}]

Commençons

ex1.reduce(selectMany(x=>x.items),[])

=> [1, 2, 4, "asda"]

ex2.reduce(selectMany(x=>x),[])

=> [1, 2, 3, 4, 5]

ex3.reduce(selectMany(x=> "this will not be called" ),[])

=> []

ex4.reduce(selectMany(x=> x.nodes ),[])

=> ["1", "v"]

NOTE: utiliser un tableau valide (non nul) comme valeur initiale dans la fonction de réduction

3
Bogdan Manole

essayez ceci (avec es6):

Array.prototype.SelectMany = function (keyGetter) {
return this.map(x=>keyGetter(x)).reduce((a, b) => a.concat(b)); 
}

exemple de tableau:

jus de fruits = [

{clé: "Apple", données: [1,2,3]},

{clé: "banane", données: [4,5,6]},

{clé: "orange", données: [7,8,9]}

]

en utilisant :

juices.SelectMany (x => x.data)

2
Cem Tuğut

Vous pouvez essayer le package manipula qui implémente toutes les méthodes C # LINQ et préserve sa syntaxe:

Manipula.from(petOwners).selectMany(x=>x.Pets).toArray()

https://github.com/litichevskiydv/manipula

https://www.npmjs.com/package/manipula

1
razon