配列内の各文字列を特定の文字列と比較したい。私の現在の実装は次のとおりです。
function startsWith(element) {
return element.indexOf(wordToCompare) === 0;
}
addressBook.filter(startsWith);
この単純な関数は動作しますが、これはwordToCompareがグローバル変数として設定されているためだけですが、もちろんこれを避けてパラメーターとして渡したいと思います。私の問題は、startsWith()を定義する方法がわからないため、余分なパラメーターを1つ受け入れることです。これは、デフォルトのパラメーターがどのように渡されるかを本当に理解していないためです。考えられるさまざまな方法をすべて試しましたが、どれも機能しません。
'ビルトイン'コールバック関数に渡されたパラメーターがどのように機能するのかを説明できたら(申し訳ありませんが、これらのより良い用語はわかりません)
startsWith
がWordを受け入れて比較するようにし、関数を返します。これはフィルター/コールバック関数として使用されます。
function startsWith(wordToCompare) {
return function(element) {
return element.indexOf(wordToCompare) === 0;
}
}
addressBook.filter(startsWith(wordToCompare));
別のオプションは Function.prototype.bind
[MDN] (ECMAScript 5をサポートするブラウザーでのみ使用可能、古いブラウザーのシムのリンクをたどる)、最初の引数を「修正」する:
function startsWith(wordToCompare, element) {
return element.indexOf(wordToCompare) === 0;
}
addressBook.filter(startsWith.bind(this, wordToCompare));
私はそれが取るデフォルトパラメータがどのように渡されるのか本当に理解していない
それについて特別なことは何もありません。ある時点で、filter
はコールバックを呼び出して、配列の現在の要素を渡すだけです。したがって、それは別の関数を呼び出す関数です。この場合、引数として渡すコールバックです。
同様の関数の例を次に示します。
function filter(array, callback) {
var result = [];
for(var i = 0, l = array.length; i < l; i++) {
if(callback(array[i])) { // here callback is called with the current element
result.Push(array[i]);
}
}
return result;
}
フィルターの2番目のパラメーターは、コールバック内でthisを設定します。
arr.filter(callback[, thisArg])
そのため、次のようなことができます。
function startsWith(element) {
return element.indexOf(this) === 0;
}
addressBook.filter(startsWith, wordToCompare);
function startsWith(element, wordToCompare) {
return element.indexOf(wordToCompare) === 0;
}
// ...
var Word = "SOMETHING";
addressBook.filter(function(element){
return startsWith(element, Word);
});
矢印関数を使用してES6の代替を探している人のために、次のことができます。
let startsWith = wordToCompare => (element, index, array) => {
return element.indexOf(wordToCompare) === 0;
}
// where Word would be your argument
let result = addressBook.filter(startsWith("Word"));
includes を使用して更新されたバージョン:
const startsWith = wordToCompare => (element, index, array) => {
return element.includes(wordToCompare);
}
次のように、フィルター内で矢印関数を使用できます。
result = addressBook.filter(element => element.indexOf(wordToCompare) === 0);
矢印関数式は、関数式と比較して構文が短く、this値を字句的にバインドします(独自のthis、arguments、super、またはnew.targetをバインドしません)。矢印関数は常に匿名です。これらの関数式は非メソッド関数に最適であり、コンストラクターとして使用することはできません。
太い矢印関数が_[, thisArg]
_を無視している理由を知りたい場合は、たとえばなぜ
["DOG", "CAT", "DOG"].filter(animal => animal === this, "DOG")
は_[]
_を返します
これは、これらの矢印関数内のthis
は、関数の作成時にバインドされ、より広い範囲でthis
の値に設定されるため、thisArg
引数は無視されるためです。親スコープで新しい変数を宣言することで、これを簡単に回避できました。
let bestPet = "DOG"; ["DOG", "CAT", "DOG"].filter(animal => animal === bestPet); => ["DOG", "DOG"]
いくつかの参考文献へのリンクを次に示します。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this
フィルター関数を使用して、すべてのパラメーターにアクセスし、複雑になりすぎないようにする簡単な方法があります。
コールバックのthisArgが別のスコープフィルターに設定されない限り、フィルターは独自のスコープを作成せず、現在のスコープ内のparamsにアクセスできます。必要に応じて他の値にアクセスするために「this」を設定して別のスコープを定義できますが、デフォルトでは呼び出し元のスコープに設定されます。 thisがAngular scopes このスタック内 に使用されていることがわかります。
IndexOfを使用すると、フィルターの目的が無効になり、オーバーヘッドが増えます。フィルターは既に配列を通過しているのに、なぜ繰り返し処理する必要があるのですか?代わりに、単純な 純粋な関数 にすることができます。
状態にitemsと呼ばれる配列があるReactクラスメソッド内のユースケースシナリオは、既存の状態を確認できるフィルター:
checkList = (item) => { // we can access this param and globals within filter
var result = this.state.filter(value => value === item); // returns array of matching items
result.length ? return `${item} exists` : this.setState({
items: items.Push(item) // bad practice, but to keep it light
});
}
oddRavenの回答と https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter に基づく
私はそれを2つの異なる方法でやった。 1)関数wayを使用します。 2)インライン方法を使用します。
//Here is sample codes :
var templateList = [
{ name: "name1", index: 1, dimension: 1 } ,
{ name: "name2", index: 2, dimension: 1 } ,
{ name: "name3", index: 3, dimension: 2 } ];
//Method 1) using function :
function getDimension1(obj) {
if (obj.dimension === 1) // This is hardcoded .
return true;
else return false;
}
var tl = templateList.filter(getDimension1); // it will return 2 results. 1st and 2nd objects.
console.log(tl) ;
//Method 2) using inline way
var tl3 = templateList.filter(element => element.index === 1 || element.dimension === 2 );
// it will return 1st and 3rd objects
console.log(tl3) ;