Leider habe ich kein JQuery oder Underscore, nur reines Javascript (IE9-kompatibel).
Ich möchte das Äquivalent von SelectMany () aus der LINQ-Funktionalität.
// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);
Kann ich es schaffen?
BEARBEITEN:
Dank der Antworten funktionierte Folgendes:
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
javascript
c#
toddmo
quelle
quelle
Antworten:
Für eine einfache Auswahl können Sie die Reduktionsfunktion von Array verwenden.
Nehmen wir an, Sie haben eine Reihe von Zahlenfeldern:
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]
Bearbeiten:
da es6 flatMap zum Array-Prototyp hinzugefügt wurde.
SelectMany
ist synonym zuflatMap
.Die Methode ordnet zuerst jedes Element mithilfe einer Zuordnungsfunktion zu und glättet dann das Ergebnis in ein neues Array. Die vereinfachte Signatur in TypeScript lautet:
function flatMap<A, B>(f: (value: A) => B[]): B[]
Um die Aufgabe zu erfüllen, müssen wir nur jedes Element auf phoneNumbers flatMap
arr.flatMap(a => a.phoneNumbers);
quelle
arr.reduce(function(a, b){ return a.concat(b.phoneNumbers); }, [])
flatMap
erfüllt aber nicht die Anforderung des OP nach einer IE9-kompatiblen Lösung - Browserkompatibel fürflatmap
.Als einfachere Option Array.prototype.flatMap () oder 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.flatMap(a => a.details); // or data.map(a => a.details).flat(1); console.log(result)
quelle
const result = data.flatMap(a => a.details)
Für diejenigen, die eine Weile später Javascript verstehen, aber dennoch eine einfache Typed SelectMany-Methode in Typescript benötigen:
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>()); }
quelle
Sagi verwendet die Concat-Methode korrekt, um ein Array zu reduzieren. Um etwas Ähnliches wie dieses Beispiel zu erhalten, benötigen Sie jedoch auch eine Karte für den ausgewählten Teil 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,[])
quelle
arr
mitpeople
und"pets"
mit"PhoneNumbers"
petOwners.map(owner => owner.Pets).reduce((a, b) => a.concat(b), []);
. Oder noch einfacherpetOwners.reduce((a, b) => a.concat(b.Pets), []);
.// 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"]}]
Lasst uns beginnen
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"]
HINWEIS: Verwenden Sie ein gültiges Array (nicht null) als Anfangswert in der Reduktionsfunktion
quelle
versuchen Sie dies (mit es6):
Array.prototype.SelectMany = function (keyGetter) { return this.map(x=>keyGetter(x)).reduce((a, b) => a.concat(b)); }
Beispielarray:
var juices=[ {key:"apple",data:[1,2,3]}, {key:"banana",data:[4,5,6]}, {key:"orange",data:[7,8,9]} ]
mit:
juices.SelectMany(x=>x.data)
quelle
Ich würde dies tun (vermeiden .concat ()):
function SelectMany(array) { var flatten = function(arr, e) { if (e && e.length) return e.reduce(flatten, arr); else arr.push(e); return arr; }; return array.reduce(flatten, []); } var nestedArray = [1,2,[3,4,[5,6,7],8],9,10]; console.log(SelectMany(nestedArray)) //[1,2,3,4,5,6,7,8,9,10]
Wenn Sie .reduce () nicht verwenden möchten:
function SelectMany(array, arr = []) { for (let item of array) { if (item && item.length) arr = SelectMany(item, arr); else arr.push(item); } return arr; }
Wenn Sie .forEach () verwenden möchten:
function SelectMany(array, arr = []) { array.forEach(e => { if (e && e.length) arr = SelectMany(e, arr); else arr.push(e); }); return arr; }
quelle
Los geht's, eine umgeschriebene Version der Antwort von Joel-Harkes in TypeScript als Erweiterung, die auf jedem Array verwendet werden kann. So können Sie es buchstäblich wie verwenden
somearray.selectMany(c=>c.someprop)
. Transpiled, das ist Javascript.declare global { interface Array<T> { selectMany<TIn, TOut>(selectListFn: (t: TIn) => TOut[]): TOut[]; } } Array.prototype.selectMany = function <TIn, TOut>( selectListFn: (t: TIn) => TOut[]): TOut[] { return this.reduce((out, inx) => { out.push(...selectListFn(inx)); return out; }, new Array<TOut>()); } export { };
quelle
Sie können das
manipula
Paket ausprobieren , das alle C # LINQ-Methoden implementiert und seine Syntax beibehält:Manipula.from(petOwners).selectMany(x=>x.Pets).toArray()
https://github.com/litichevskiydv/manipula
https://www.npmjs.com/package/manipula
quelle