Sayangnya, saya tidak memiliki JQuery atau Underscore, hanya javascript murni (kompatibel dengan IE9).
Saya menginginkan fungsi yang setara dengan SelectMany () dari LINQ.
// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);
Bisakah saya melakukannya?
EDIT:
Berkat jawaban, saya mendapatkan ini berfungsi:
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
sumber
sumber
Jawaban:
untuk pemilihan sederhana Anda dapat menggunakan fungsi pengurangan Array.
Katakanlah Anda memiliki array array angka:
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]
Sunting:
karena es6 flatMap telah ditambahkan ke prototipe Array.
SelectMany
adalah sinonim denganflatMap
.Metode ini pertama-tama memetakan setiap elemen menggunakan fungsi pemetaan, kemudian meratakan hasilnya ke dalam array baru. Tanda tangannya yang disederhanakan di TypeScript adalah:
function flatMap<A, B>(f: (value: A) => B[]): B[]
Untuk mencapai tugas tersebut kita hanya perlu melakukan flatMap setiap elemen ke phoneNumbers
arr.flatMap(a => a.phoneNumbers);
sumber
arr.reduce(function(a, b){ return a.concat(b.phoneNumbers); }, [])
flatMap
tidak memenuhi permintaan OP untuk solusi yang kompatibel dengan IE9 - browser compat forflatmap
.Sebagai opsi yang lebih sederhana Array.prototype.flatMap () atau 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)
sumber
const result = data.flatMap(a => a.details)
Untuk beberapa waktu kemudian, memahami javascript tetapi masih menginginkan metode SelectMany Ketik yang sederhana di Typecript:
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>()); }
sumber
Sagi benar dalam menggunakan metode concat untuk meratakan array. Tetapi untuk mendapatkan sesuatu yang mirip dengan contoh ini, Anda juga memerlukan peta untuk bagian tertentu 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,[])
sumber
arr
denganpeople
dan"pets"
dengan"PhoneNumbers"
petOwners.map(owner => owner.Pets).reduce((a, b) => a.concat(b), []);
. Atau, bahkan lebih sederhanapetOwners.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"]}]
Ayo mulai
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"]
CATATAN: gunakan array yang valid (bukan null) sebagai nilai intisial dalam fungsi pengurangan
sumber
coba ini (dengan es6):
Array.prototype.SelectMany = function (keyGetter) { return this.map(x=>keyGetter(x)).reduce((a, b) => a.concat(b)); }
contoh larik:
var juices=[ {key:"apple",data:[1,2,3]}, {key:"banana",data:[4,5,6]}, {key:"orange",data:[7,8,9]} ]
menggunakan:
juices.SelectMany(x=>x.data)
sumber
Saya akan melakukan ini (menghindari .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]
Jika Anda tidak ingin menggunakan .reduce ():
function SelectMany(array, arr = []) { for (let item of array) { if (item && item.length) arr = SelectMany(item, arr); else arr.push(item); } return arr; }
Jika Anda ingin menggunakan .forEach ():
function SelectMany(array, arr = []) { array.forEach(e => { if (e && e.length) arr = SelectMany(e, arr); else arr.push(e); }); return arr; }
sumber
Ini dia, versi jawaban joel-harkes yang ditulis ulang di TypeScript sebagai ekstensi, dapat digunakan pada array apa pun. Jadi Anda benar-benar dapat menggunakannya seperti
somearray.selectMany(c=>c.someprop)
. Bertransaksi, ini 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 { };
sumber
Anda dapat mencoba
manipula
paket yang mengimplementasikan semua metode C # LINQ dan mempertahankan sintaksnya:Manipula.from(petOwners).selectMany(x=>x.Pets).toArray()
https://github.com/litichevskiydv/manipula
https://www.npmjs.com/package/manipula
sumber