Unfortunately, I don't have JQuery or Underscore, just pure javascript (IE9 compatible).
I'm wanting the equivalent of SelectMany() from LINQ functionality.
// SelectMany flattens it to just a list of phone numbers. IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);
Can I do it?
EDIT:
Thanks to answers, I got this working:
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
Select and SelectMany are projection operators. A select operator is used to select value from a collection and SelectMany operator is used to selecting values from a collection of collection i.e. nested collection.
What is Linq SelectMany? The SelectMany in LINQ is used to project each element of a sequence to an IEnumerable<T> and then flatten the resulting sequences into one sequence. That means the SelectMany operator combines the records from a sequence of results and then converts it into one result.
This is the right answer if you can use it. It is an equivalent function to Linq.Any () If you need IE8 compatibility, then this is not an option. Update: In ES6 / ECMAScript 2015, you can do myArray.some (c=>c) to mimic exactly what LINQ does with .Any (). Noting that in LINQ the .Any () method doesn't require a delegate, whereas .some () does.
Update: In ES6 / ECMAScript 2015, you can do myArray.some (c=>c) to mimic exactly what LINQ does with .Any (). Noting that in LINQ the .Any () method doesn't require a delegate, whereas .some () does. Attempting to call .some () without a delegate will result in an error as the delegate will be undefined.
With .net, using LINQ, we could do a simple Lambda: .Select(x=> x.id) 1 Select(x=>x.id) With Javascript, we can use Map to achieve something similar: products.map(function(product) { return product.id }) 1 2
If there was a utility function like $.is I'd feel safer, but this appears to be an undocumented "feature" AFAIK jQuery selections are native arrays (or at least they use Array.prototype ), and there is probably enough code in the wild relying on it that it can never change.
for a simple select you can use the reduce function of Array.
Lets say you have an array of arrays of numbers:
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]
Edit:
since es6 flatMap has been added to the Array prototype. SelectMany
is synonym to flatMap
.
The method first maps each element using a mapping function, then flattens the result into a new array. Its simplified signature in TypeScript is:
function flatMap<A, B>(f: (value: A) => B[]): B[]
In order to achieve the task we just need to flatMap each element to phoneNumbers
arr.flatMap(a => a.phoneNumbers);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With