Javascript is equivalent to C # LINQ Select

Following this question:

Using the checked binding in the knockout with the list of flags, check all the flags

I created some checkboxes using knockout that allow you to select from an array. working violin taken at the top of the message:

http://jsfiddle.net/NsCXJ/

Is there an easy way to create an array of only fruit identifiers?

I am more at home with C #, where I would do something along the lines of selectedFruits.select(fruit=>fruit.id);

Is there some kind of method / ready-made function to do something similar with javascript / jquery? Or the easiest option is to iterate over the list and create a second array? I intend to send the array back to the server in JSON, so I try to minimize the data sent.

+108
javascript jquery
Sep 21 '13 at 19:34
source share
10 answers

Yes, Array.map () or $ .map () does the same.

 //array.map: var ids = this.fruits.map(function(v){ return v.Id; }); //jQuery.map: var ids2 = $.map(this.fruits, function (v){ return v.Id; }); console.log(ids, ids2); 

http://jsfiddle.net/NsCXJ/1/

Since array.map is not supported in older browsers, I suggest sticking with the jQuery method.

If for some reason you prefer another, you can always add a polyfill to support the old browser.

You can always add your own methods to the prototype array:

 Array.prototype.select = function(expr){ var arr = this; //do custom stuff return arr.map(expr); //or $.map(expr); }; var ids = this.fruits.select(function(v){ return v.Id; }); 



An extended version that uses a function constructor if you pass a string. Perhaps you can play with this:

 Array.prototype.select = function(expr){ var arr = this; switch(typeof expr){ case 'function': return $.map(arr, expr); break; case 'string': try{ var func = new Function(expr.split('.')[0], 'return ' + expr + ';'); return $.map(arr, func); }catch(e){ return null; } break; default: throw new ReferenceError('expr not defined or not supported'); break; } }; console.log(fruits.select('x.Id')); 

http://jsfiddle.net/aL85j/

Update:

Since this has become such a popular answer, I add a similar firstOrDefault() where() + firstOrDefault() . They can also be used with the string-based function constructor approach (which is the fastest), but there is another approach here that uses the object literal as a filter:

 Array.prototype.where = function (filter) { var collection = this; switch(typeof filter) { case 'function': return $.grep(collection, filter); case 'object': for(var property in filter) { if(!filter.hasOwnProperty(property)) continue; // ignore inherited properties collection = $.grep(collection, function (item) { return item[property] === filter[property]; }); } return collection.slice(0); // copy the array // (in case of empty object filter) default: throw new TypeError('func must be either a' + 'function or an object of properties and values to filter by'); } }; Array.prototype.firstOrDefault = function(func){ return this.where(func)[0] || null; }; 

Using:

 var persons = [{ name: 'foo', age: 1 }, { name: 'bar', age: 2 }]; // returns an array with one element: var result1 = persons.where({ age: 1, name: 'foo' }); // returns the first matching item in the array, or null if no match var result2 = persons.firstOrDefault({ age: 1, name: 'foo' }); 

Here is a jsperf test to compare the constructor of a function and the speed of an object literal. If you decide to use the first, keep in mind that the lines must be specified correctly.

Personally, I prefer to use solutions based on object literals when filtering 1-2 properties and pass a callback function for more complex filtering.

I will end this with two general tips when adding methods to my own object prototypes:

  1. Check for existing methods before overwriting, for example:

    if(!Array.prototype.where) { Array.prototype.where =...

  2. If you do not need to support IE8 and lower, define methods using Object.defineProperty to make them non-enumerable. If someone used for..in in an array (which is primarily wrong), it will also perform iterable properties. Just one on one.

+178
Sep 21 '13 at 19:37
source share

I know this is a late answer, but it was useful to me! To finish using the $.grep function, you can emulate linq where() .

Linq:

 var maleNames = people .Where(p => p.Sex == "M") .Select(p => p.Name) 

JavaScript:

 // replace where with $.grep // select with $.map var maleNames = $.grep(people, function (p) { return p.Sex == 'M'; }) .map(function (p) { return p.Name; }); 
+32
May 15 '14 at 14:35
source share

Since you are using knockout, you must use the knockout utility function arrayMap() and other array utility functions.

The array utility functions and their equivalent LINQ methods are listed here:

 arrayFilter() -> Where() arrayFirst() -> First() arrayForEach() -> (no direct equivalent) arrayGetDistictValues() -> Distinct() arrayIndexOf() -> IndexOf() arrayMap() -> Select() arrayPushAll() -> (no direct equivalent) arrayRemoveItem() -> (no direct equivalent) compareArrays() -> (no direct equivalent) 

So what could you do in your example:

 var mapped = ko.utils.arrayMap(selectedFruits, function (fruit) { return fruit.id; }); 

If you need a LINQ-like interface in javascript, you can use a library like linq.js , which offers a nice interface for many LINQ methods.

 var mapped = Enumerable.From(selectedFruits) .Select("$.id") // 1 of 3 different ways to specify a selector function .ToArray(); 
+13
Sep 21 '13 at 22:12
source share

ES6 path:

 let people = [{firstName:'Alice',lastName:'Cooper'},{firstName:'Bob',age:'Dylan'}]; let names = Array.from(people, p => p.firstName); for (let name of names) { console.log(name); } 

also at: https://jsfiddle.net/52dpucey/

+10
Dec 19 '16 at 15:41
source share

You can also try linq.js

In linq.js your

 selectedFruits.select(fruit=>fruit.id); 

will be

 Enumerable.From(selectedFruits).Select(function (fruit) { return fruit.id; }); 
+9
Mar 02 '15 at 8:50
source share

Take a look at underscore.js , which provides many features similar to linq. In the above example, you will use the map function.

+2
Sep 21 '13 at 19:47
source share

I created the Linq library for TypeScript under TsLinq.codeplex.com , which you can use for simple javascript. This library is 2-3 times faster than Linq.js and contains unit tests for all Linq methods. Perhaps you could view this one.

+2
May 15 '14 at 14:13
source share

Dinqyjs has linq-like syntax and provides policies for functions such as map and indexOf, and has been developed specifically for working with arrays in Javascript.

0
Jan 02 '15 at 0:33
source share

The following is an example JavaScript structure using Linq-style syntax using ES6. http://www.syntaxsuccess.com/viewarticle/554e3b38dee3b4986d7466f8

The project installs broadcast in ES5 through Babel.

0
May 9 '15 at 17:09
source share

Try the following JS libraries. but i did not use them

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

https://archive.codeplex.com/?p=linqjs

-2
Dec 20 '18 at 13:10
source share



All Articles