Tak, Array.map () lub $ .map () robi to samo.
//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/
Ponieważ array.map nie jest obsługiwana w starszych przeglądarkach, sugeruję trzymać się metody jQuery.
Jeśli z jakiegoś powodu wolisz inny, zawsze możesz dodać polyfill do obsługi starej przeglądarki.
Zawsze możesz również dodać własne metody do prototypu tablicy:
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;
});
Rozszerzona wersja, która używa konstruktora funkcji, jeśli przekazujesz ciąg. Może coś do zabawy:
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/
Aktualizacja:
Ponieważ ta odpowiedź stała się tak popularna, dodaję podobny mój where()
+ firstOrDefault()
. Można ich również użyć z podejściem konstruktora funkcji opartym na ciągach (które jest najszybsze), ale tutaj jest inne podejście wykorzystujące literał obiektu jako filtr:
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;
};
Stosowanie:
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' });
Oto test jsperf, aby porównać konstruktor funkcji z prędkością literału obiektu. Jeśli zdecydujesz się na użycie pierwszego, pamiętaj o poprawnym cytowaniu ciągów znaków.
Osobiście wolę używać rozwiązań opartych na literałach obiektów podczas filtrowania 1-2 właściwości i przekazywać funkcję zwrotną w celu bardziej złożonego filtrowania.
Zakończę dwoma ogólnymi wskazówkami dotyczącymi dodawania metod do prototypów obiektów natywnych:
Sprawdź występowanie istniejących metod przed nadpisaniem, np .:
if(!Array.prototype.where) {
Array.prototype.where = ...
Jeśli nie potrzebujesz obsługi IE8 i starszych , zdefiniuj metody przy użyciu Object.defineProperty, aby uczynić je nieliczalnymi . Jeśli ktoś użyje for..in
tablicy (co jest błędne w pierwszej kolejności), będzie iterował również wyliczalne właściwości. Tylko jedno ostrzeżenie.
return typeof item[property] === 'function' ? item[property]() === filter[property] : item[property] === filter[property];
return ko.unwrap(item[property]) === filter[property]
?Wiem, że to późna odpowiedź, ale mi się przydała! Na koniec, używając
$.grep
funkcji możesz emulować linqwhere()
.Linq:
JavaScript:
źródło
Ponieważ używasz knockout, powinieneś rozważyć użycie funkcji narzędzia knockout
arrayMap()
i innych funkcji narzędziowych tablicy.Oto lista funkcji narzędziowych tablic i ich równoważnych metod LINQ:
Oto co możesz zrobić na swoim przykładzie:
Jeśli chcesz mieć interfejs podobny do LINQ w javascript, możesz użyć biblioteki, takiej jak linq.js, która oferuje ładny interfejs dla wielu metod LINQ.
źródło
Sposób ES6:
również pod adresem : https://jsfiddle.net/52dpucey/
źródło
Możesz też spróbować
linq.js
W
linq.js
twoimbędzie
źródło
Zbudowałem bibliotekę Linq dla TypeScript pod TsLinq.codeplex.com , której możesz użyć również dla zwykłego javascript. Ta biblioteka jest 2-3 razy szybsza niż Linq.js i zawiera testy jednostkowe dla wszystkich metod Linq. Może mógłbyś to przejrzeć.
źródło
Rzuć okiem na underscore.js, który udostępnia wiele funkcji podobnych do linq. W podanym przykładzie użyłbyś funkcji map.
źródło
Możesz wypróbować
manipula
pakiet, który implementuje wszystkie metody C # LINQ i zapisać jego składnię: https://github.com/litichevskiydv/manipulahttps://www.npmjs.com/package/manipula
Twój przykład
selectedFruits.select(fruit=>fruit.id);
zostanie zaimplementowany za pomocą manipula asźródło
Dinqyjs ma składnię podobną do linq i zapewnia wypełniacze dla funkcji takich jak map i indexOf, a także został zaprojektowany specjalnie do pracy z tablicami w JavaScript.
źródło
Spójrz na płynność , obsługuje prawie wszystko, co robi LINQ i opiera się na iterowalnych - więc działa z mapami, funkcjami generatora, tablicami, wszystkim iterowalnym.
źródło
Najbardziej podobnym
Select
analogiem C # byłabymap
funkcja. Po prostu użyj:aby wybrać wszystkie identyfikatory z
selectedFruits
tablicy.Nie wymaga żadnych zewnętrznych zależności, wystarczy czysty JavaScript.
map
Dokumentację można znaleźć tutaj: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/mapźródło
Odpowiadam raczej na tytuł pytania niż na pytanie oryginalne, które było bardziej szczegółowe.
Dzięki nowym funkcjom Javascript, takim jak iteratory i funkcje generatora oraz obiekty, możliwe staje się coś takiego jak LINQ for Javascript. Zwróć uwagę, że linq.js, na przykład, używa zupełnie innego podejścia, używając wyrażeń regularnych, prawdopodobnie w celu przezwyciężenia braku obsługi języka w tamtym czasie.
Mając to na uwadze, napisałem bibliotekę LINQ dla Javascript i możesz ją znaleźć na https://github.com/Siderite/LInQer . Komentarze i dyskusja na https://siderite.dev/blog/linq-in-javascript-linqer .
Z poprzednich odpowiedzi wynika, że tylko Manipula wydaje się być tym, czego można by oczekiwać po porcie LINQ w JavaScript.
źródło