161

ここでこの質問に続いて:

チェックボックスのリストを含むノックアウトでチェック済みバインディングを使用すると、すべてのチェックボックスがチェックされます

ノックアウトを使用して、配列から選択できるチェックボックスをいくつか作成しました。上記の投稿から取得した作業フィドル:

http://jsfiddle.net/NsCXJ/

果物の ID だけの配列を作成する簡単な方法はありますか?

私はC#にもっと慣れていて、次のようなことをしますselectedFruits.select(fruit=>fruit.id);

javascript/jqueryで同様のことを行うためのメソッド/既製の関数はありますか? または、最も簡単なオプションは、リストをループして 2 番目の配列を作成することでしょうか? 配列を JSON でサーバーに戻すつもりなので、送信されるデータを最小限に抑えようとしています。

4

13 に答える 13

255

はい、Array.map()または$.map()は同じことを行います。

//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/

array.map は古いブラウザーではサポートされていないため、jQuery メソッドを使用することをお勧めします。

何らかの理由で他のものを好む場合は、古いブラウザのサポートのためにいつでもポリフィルを追加できます。

カスタム メソッドをいつでも配列プロトタイプに追加することもできます。

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;
});

文字列を渡す場合に関数コンストラクターを使用する拡張バージョン。おそらく何かをいじる:

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/

アップデート:

これは非常に人気のある回答になっているので、同様のwhere()+ を追加しfirstOrDefault()ます。これらは、文字列ベースの関数コンストラクター アプローチ (最速) で使用することもできますが、オブジェクト リテラルをフィルターとして使用する別のアプローチを次に示します。

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;
};

使用法:

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' }); 

関数コンストラクターとオブジェクト リテラルの速度を比較するjsperfテストを次に示します。前者を使用する場合は、文字列を正しく引用することに注意してください。

私の個人的な好みは、1 ~ 2 個のプロパティをフィルター処理するときにオブジェクト リテラル ベースのソリューションを使用し、より複雑なフィルター処理のためにコールバック関数を渡すことです。

最後に、メソッドをネイティブ オブジェクト プロトタイプに追加する際の一般的なヒントを 2 つ紹介します。

  1. 上書きする前に、既存のメソッドの出現を確認してください。

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

  2. IE8 以下をサポートする必要がない場合は、Object.definePropertyを使用してメソッドを定義し、列挙できないようにします。誰かがfor..in配列で使用した場合 (これはそもそも間違っています)、列挙可能なプロパティも反復処理します。ただ頭を上げてください。

于 2013-09-21T19:37:41.397 に答える
33

私はそれが遅い答えであることを知っていますが、それは私にとって役に立ちました! 完了するために、$.grep関数を使用して linq をエミュレートできますwhere()

リンク:

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; });
于 2014-05-15T14:35:10.783 に答える
17

ES6 の方法:

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);
}

また: https://jsfiddle.net/52dpucey/

于 2016-12-19T15:41:28.263 に答える
3

TypeScript 用の Linq ライブラリをTsLinq.codeplex.comの下に構築しました。これはプレーンな JavaScript にも使用できます。このライブラリは、Linq.js よりも 2 ~ 3 倍高速で、すべての Linq メソッドの単体テストが含まれています。たぶん、あなたはそれをレビューすることができます。

于 2014-05-15T14:13:30.433 に答える
-1

より具体的な元の質問ではなく、質問のタイトルに答えています。

イテレータ、ジェネレータ関数、オブジェクトなどの Javascript の新機能により、LINQ for Javascript のようなものが可能になります。たとえば、linq.js は正規表現を使用するまったく異なるアプローチを使用していることに注意してください。おそらく、当時の言語でのサポート不足を克服するためです。

そうは言っても、私は Javascript 用の LINQ ライブラリを作成しました。https://github.com/Siderite/LInQerで見つけることができます。https://siderite.dev/blog/linq-in-javascript-linqerでのコメントとディスカッション。

以前の回答から、Javascript の LINQ ポートに期待されるのは Manipula だけのようです。

于 2020-01-06T16:22:56.713 に答える