Sim, Array.map () ou $ .map () fazem a mesma coisa.
//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/
Como o array.map não é suportado em navegadores antigos, sugiro que você siga o método jQuery.
Se você preferir o outro por algum motivo, sempre poderá adicionar um polyfill para suporte ao navegador antigo.
Você também pode adicionar métodos personalizados ao protótipo da matriz:
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;
});
Uma versão estendida que usa o construtor da função se você passar uma string. Algo para brincar, talvez:
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/
Atualizar:
Como essa se tornou uma resposta tão popular, estou adicionando meu where()
+ semelhante firstOrDefault()
. Eles também podem ser usados com a abordagem do construtor de função baseada em string (que é a mais rápida), mas aqui está outra abordagem usando um literal de objeto como filtro:
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;
};
Uso:
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' });
Aqui está um teste jsperf para comparar a velocidade literal do construtor de funções versus a velocidade do objeto. Se você decidir usar o primeiro, lembre-se de citar as strings corretamente.
Minha preferência pessoal é usar as soluções baseadas em objetos literais ao filtrar 1-2 propriedades e passar uma função de retorno de chamada para uma filtragem mais complexa.
Terminarei com duas dicas gerais ao adicionar métodos a protótipos de objetos nativos:
Verifique a ocorrência de métodos existentes antes de substituir, por exemplo:
if(!Array.prototype.where) {
Array.prototype.where = ...
Se você não precisar oferecer suporte ao IE8 e abaixo, defina os métodos usando Object.defineProperty para torná-los não enumeráveis. Se alguém usado for..in
em uma matriz (o que está errado em primeiro lugar), ele também iterará inúmeras propriedades. Apenas um aviso.
return typeof item[property] === 'function' ? item[property]() === filter[property] : item[property] === filter[property];
return ko.unwrap(item[property]) === filter[property]
?Eu sei que é uma resposta tardia, mas foi útil para mim! Apenas para concluir, usando a
$.grep
função, você pode emular o linqwhere()
.Linq:
Javascript:
fonte
Como você está usando knockout, considere usar a função do utilitário knockout
arrayMap()
e outras funções do array array.Aqui está uma lista de funções utilitárias de matriz e seus métodos LINQ equivalentes:
Então, o que você poderia fazer no seu exemplo é o seguinte:
Se você deseja uma interface semelhante ao LINQ em javascript, pode usar uma biblioteca como linq.js, que oferece uma interface agradável para muitos dos métodos LINQ.
fonte
A maneira ES6:
também em: https://jsfiddle.net/52dpucey/
fonte
Você também pode tentar
linq.js
No
linq.js
seuserá
fonte
Criei uma biblioteca Linq para TypeScript em TsLinq.codeplex.com que você também pode usar para javascript simples. Essa biblioteca é 2-3 vezes mais rápida que o Linq.js e contém testes de unidade para todos os métodos do Linq. Talvez você possa revisar essa.
fonte
Dê uma olhada no underscore.js, que fornece muitas funções do tipo linq. No exemplo que você deu, você usaria a função map.
fonte
Você pode experimentar o
manipula
pacote, que implementa todos os métodos C # LINQ e salva sua sintaxe: https://github.com/litichevskiydv/manipulahttps://www.npmjs.com/package/manipula
Seu exemplo
selectedFruits.select(fruit=>fruit.id);
será implementado com manipulação comofonte
O Dinqyjs possui uma sintaxe do tipo linq e fornece polyfills para funções como map e indexOf, e foi projetado especificamente para trabalhar com matrizes em Javascript.
fonte
Dê uma olhada no fluente , ele suporta quase tudo o que o LINQ faz e com base em iteráveis - para que ele funcione com mapas, funções de gerador, matrizes, tudo que é iterável.
fonte
O análogo C # mais semelhante
Select
seria umamap
função. Apenas use:para selecionar todos os IDs da
selectedFruits
matriz.Não requer nenhuma dependência externa, apenas JavaScript puro. Você pode encontrar
map
documentação aqui: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/mapfonte
Estou respondendo ao título da pergunta, e não à pergunta original, que era mais específica.
Com os novos recursos do Javascript, como iteradores e funções e objetos do gerador, algo como o LINQ for Javascript se torna possível. Observe que o linq.js, por exemplo, usa uma abordagem completamente diferente, usando expressões regulares, provavelmente para superar a falta de suporte no idioma da época.
Com isso dito, escrevi uma biblioteca LINQ para Javascript e você pode encontrá-la em https://github.com/Siderite/LInQer . Comentários e discussão em https://siderite.dev/blog/linq-in-javascript-linqer .
Das respostas anteriores, apenas Manipula parece ser o que seria de esperar de uma porta LINQ em Javascript.
fonte