[解決済み] ko.utils.arrayMap で、配列の一部しか返さない。
質問
Knockoutのユーティリティ機能を使用しています。 http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html
ある条件に基づいて特定のプロパティを選択するarrayMapをしたい、など。
return ko.utils.arrayMap(myObservableArray(), function (item) {
return item.Label;
});
例えば、これが次のような出力になったとする。
[null, "", "SomeLabel", null, "SomeOtherLabel"]
条件に基づいてプロパティを選択したいので、試してみます。
return ko.utils.arrayMap(myObservableArray(), function (item) {
if (item.Label && item.Label !== "") {
return item.Label;
}
});
しかし、そうすると、次のような配列になってしまいます。
[undefined, undefined, "SomeLabel", undefined, "SomeOtherLabel"]
こんなこともやってみました。
return ko.utils.arrayMap(myObservableArray(), function (item) {
return (item.Label && item.Label !== "") ? item.Label : false;
});
が、得られる。
[false, false, "SomeLabel", false, "SomeOtherLabel"]
だから、私はその後、しなければならないのです。
var itemsWithLabels = ko.utils.arrayFilter(myObservableArray(), function (item) {
return (item.Label && item.Label !== "");
});
return ko.utils.arrayMap(itemsWithLabels, function (item) {
return item.Label;
});
というのが出てきます。
["SomeLabel", "SomeOtherLabel"]
ko.utilsなどを使って一発で達成できる、より効率的な方法はないでしょうか?
どのように解決するのですか?
お気づきのように、ko.utils.arrayMapでは、コールバックが何かを返すことが期待されています。したがって、これは常にコールバックの戻り値を配列に追加する「ダム関数」です。未定義、ヌル、または偽を返しても、結果の配列から値を省略することはありません。
arrayFilter は、フィルタリングされた項目を変更することはできません。 元の項目が結果配列にプッシュされることになります。
つまり、ko.utils.array*の関数を使っても、これ以上の効率は望めないということです。それらを組み合わせて、コードをもう少し冗長にして、おそらくそれらを計算機に入れることもできます。
var itemsWithLabels = ko.computed(function () {
return ko.utils.arrayMap(ko.utils.arrayFilter(myObservableArray(), function (item) {
return item.Label && item.Label.length;
}), function (filteredItem) {
return filteredItem.Label;
});
});
でも、これが精一杯なんですよね。最初にフィルタをかけて、その後にマッピングを行うという方法を選んだのは、マッピングの方がフィルタリングよりもコストがかかりそうだからです。でも、これは単なる勘ですけどね。
Underscoreのようなライブラリが、これを直接行うメソッドを提供しているのかもしれませんね。
また、このようなメソッドを自分で書くこともかなり簡単です(必要であればko.utilsに入れることも可能です)。
ko.utils.arrayMapFilter = function (array, mapping) {
array = array || [];
var result = [], mapResult;
for (var i = 0, j = array.length; i < j; i++) {
mapResult = mapping(array[i]);
if (mapResult) {
result.push(mapResult);
}
}
return result;
},
マッピングコールバックは 0, "", false, null, undefined などの偽の値を返すことができるようになり、これらは配列に含まれなくなりました。
もし上記の値のうちのいくつかをとにかく許可したいのであれば(例えば0や"")、その行を変更するだけです。
if (mapResult)
のような、より厳密なものに変更します。
if (mapResult !== undefined && mapResult !== null)
関連
-
[解決済み】XMLHttpRequestモジュールが定義されていない/見つからない
-
[解決済み】NodeJS "ESモジュールをロードするためにインポートを使用する必要があります。"
-
[解決済み】WebpackとBabelで「このファイルタイプを扱うには適切なローダーが必要な場合があります。
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] JavaScript で配列に値が含まれているかどうかを確認するにはどうすればよいですか?
-
[解決済み] event.preventDefault() vs. return false
-
[解決済み】オブジェクトの配列を文字列のプロパティ値でソートする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Uncaught TypeError: 未定義のプロパティ 'top' を読み込めない
-
[解決済み】Angular JS Uncaught Error。[インジェクター:モジュラー]。
-
[解決済み] Uncaught Invariant Violation: 前のレンダリング中よりも多くのフックをレンダリングした
-
[解決済み] 解決済み】clearInterval()が動作しない [重複] [重複]
-
[解決済み】「Uncaught TypeError: Chromeで "Illegal invocation "が発生する。
-
[解決済み】SyntaxError: 'import' と 'export' は 'sourceType: module' とだけ表示されるかもしれない - Gulp
-
[解決済み】SyntaxError: ChromeのJavascriptコンソールでUnexpected Identifierが発生する。
-
[解決済み】このオブジェクトの "forEach "はなぜ関数でないのですか?
-
[解決済み】'useState' が定義されていない no-undef React
-
[解決済み】react router v^4.0.0 Uncaught TypeError: 未定義のプロパティ'location'を読み取れない