文字列に配列の要素が含まれているかどうかを確認するにはどうすればよいですか?要素に文字列がある場合、配列をフィルタリングしたい。以下のコードをご覧ください。
var arr = ['banana', 'monkey banana', 'Apple', 'kiwi', 'orange'];
function checker(value) {
var prohibited = ['banana', 'Apple'];
for (var i = 0; i < prohibited.length; i++) {
if (value.indexOf(prohibited[i]) == -1) {
return true;
} else {
return false;
}
}
}
arr = arr.filter(checker);
console.log(arr);
結果は[ 'Apple', 'kiwi', 'orange' ]
。 'Apple'
は削除されますが、削除されません。
上記のコードは「バナナ」のみをフィルタリングし、「アップル」はフィルタリングしません。フィルタリングする多くのキーワードがあります。もっと簡単な方法はありますか?
問題はforループにあります。forループは、戻り値が関数を終了してプロセスのforループを切断するため、1回だけ繰り返されます。そのため、forループが完了した後にのみ関数が戻るようにコードを更新できます。
_var arr = ['banana', 'monkey banana', 'Apple', 'kiwi', 'orange'];
function checker(value) {
var prohibited = ['banana', 'Apple'];
for (var i = 0; i < prohibited.length; i++) {
if (value.indexOf(prohibited[i]) > -1) {
return false;
}
}
return true;
}
arr = arr.filter(checker);
console.log(arr);
_
関数を削減するには、every()
(および- indexOf()
メソッド
'every'メソッドは、コールバックが偽の値(ブール値に変換されるとfalseになる値)を返す要素が見つかるまで、配列に存在する各要素に対して提供されたコールバック関数を1回実行します。そのような要素が見つかった場合、everyメソッドはすぐにfalseを返します。それ以外の場合、コールバックがすべての要素に対してtrue値を返した場合、everyはtrueを返します。コールバックは、値が割り当てられた配列のインデックスに対してのみ呼び出されます。削除されたインデックスまたは値が割り当てられていないインデックスに対しては呼び出されません。(ここから取得)
_var arr = ['banana', 'monkey banana', 'Apple', 'kiwi', 'orange'];
function checker(value) {
var prohibited = ['banana', 'Apple'];
return prohibited.every(function(v) {
return value.indexOf(v) == -1;
});
}
arr = arr.filter(checker);
console.log(arr);
_
古いブラウザの場合 すべてのメソッドのpolyfillオプションをチェック 。
ここで正規表現を使用することもできます。配列を使用して正規表現を生成し、test()
を使用して一致を確認します
_var arr = ['banana', 'monkey banana', 'Apple', 'kiwi', 'orange'];
function checker(value) {
var prohibited = ['banana', 'Apple'];
var regex = new RegExp(prohibited.map(function(s) {
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}).join('|'));
return !regex.test(value);
}
arr = arr.filter(checker);
console.log(arr);
_
文字列から正規表現への変換については、この回答を参照してください: 文字列変数を使用してJavaScript正規表現をその場で作成できますか?
それと同じくらい簡単です:
_const arr = ['banana', 'monkey banana', 'Apple', 'kiwi', 'orange'];
const checker = value =>
!['banana', 'Apple'].some(element => value.includes(element));
console.log(arr.filter(checker));
_
ECMAScript 6 FTW!
checker
は 矢印関数 を使用します。
_!
_は、条件を満たさないすべての要素を除外することを意味します。
some()
メソッドは、配列内の一部の要素が、提供された関数によって実装されたテストに合格するかどうかをテストします。
from Array.prototype.some()
MDMのドキュメント
includes()
メソッドは、ある文字列が別の文字列内で見つかるかどうかを判断し、true
またはfalse
適切に。
from String.prototype.includes()
MDMのドキュメント
一部の最新のECMAScript機能はすべてのブラウザでサポートされていないため、 Babel を使用してコードをECMAScript 5にコンパイルする必要があります。
これは非常に単純化できると思います。これらのことをチェックするためのJavaScriptがすでに組み込まれています。考慮してください:
var arr = ['banana', 'monkey banana', 'Apple', 'kiwi', 'orange'];
function checker(value) {
var prohibited = ['banana', 'Apple'];
// indexOf() returns -1 if the element doesn't exist in the prohibited array
return prohibited.indexOf( value ) == -1;
}
arr = arr.filter(checker);
console.log(arr);
これは疑わしい慣習であると主張する人もいるかもしれませんが、文字列で直接実行できるメソッドがあると便利な場合があります。この場合、JavaScript String を拡張できます String.prototype を使用するオブジェクト。
このように...
String.prototype.containsAny = String.prototype.containsAny || function(arr) {
for (var i = 0; i < arr.length; i++) {
if (this.indexOf(arr[i]) > -1) {
return true;
}
}
return false;
};
この例からわかるように、containsAny
メソッドの既存の定義がデフォルトになります。念頭に置いてください:組み込みオブジェクトを増やす場合は、少なくとも最初にプロパティの存在を確認することをお勧めします-おそらくいつかは存在するでしょう...¯\_(ツ)_ /¯
使用方法については、 このフィドル を確認するか、以下を参照してください:
var str = 'This is a sentence as a string.';
console.log(str.containsAny(['string1', 'string2', 'string3'])); // -> returns false
console.log(str.containsAny(['string', 'string1', 'string2'])); // -> returns true
<script src="//cdn.simpledigital.net/common/js/extensions/String.prototypeHelpers.js"></script>
たとえば、RegExpを構築し、それに対してテストすることにより:
var arr = ['banana', 'monkey banana', 'Apple', 'kiwi', 'orange'];
var prohibited = ['banana', 'Apple'];
var escapeForRegex = function(str) {
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
var r = new RegExp(prohibited.map(escapeForRegex).join("|"));
arr.filter(function(v){ return !r.test(v) });