2017-03-14 14 views
0

製品グリッドフィルタリングシステムを作成しようとしています。 JSONオブジェクトの.filter()を呼び出すと、私が探している結果が得られます。.filter()を使用したAND/ORロジック

const filteredProducts = allProducts.filter((a) => { 
    // return brown or blue products in with omnis tag 
    const prodTags = a.tags; 
    return (
    prodTags.includes('brown') && prodTags.includes('single-eye') && prodTags.includes('happy') || 
    prodTags.includes('brown') && prodTags.includes('single-eye') && prodTags.includes('angry') || 
    prodTags.includes('brown') && prodTags.includes('two-eyes') && prodTags.includes('happy') || 
    prodTags.includes('brown') && prodTags.includes('two-eyes') && prodTags.includes('angry') || 
    prodTags.includes('blue') && prodTags.includes('single-eye') && prodTags.includes('happy') || 
    prodTags.includes('blue') && prodTags.includes('single-eye') && prodTags.includes('angry') || 
    prodTags.includes('blue') && prodTags.includes('two-eyes') && prodTags.includes('happy') || 
    prodTags.includes('blue') && prodTags.includes('two-eyes') && prodTags.includes('angry') 
); 
}); 

私はこの動的な方法を考えるのに苦労しています。私は、このロジックを任意の数のタグに対して自動的に生成できる関数を作成するように思えます。

私は(〜現在選択されたものである)、このようになりますフィルタリングシステムがあります。

----------- 
Colors: 
----------- 
~ brown 
gray 
~ blue 
pink 


----------- 
Eyes: 
----------- 
~ single-eye 
~ two-eyes 


----------- 
Emotion: 
----------- 
~ happy 
~ angry 
sad 

をカテゴリー間のロジックがあると。カテゴリの値間の論理はORです。私は、デカルト積配列を作成する関数セットアップを持っています。選択したフィルタ配列は次のようになります。

[ 
    ['brown', 'single-eye', 'angry'], 
    ['brown', 'single-eye', 'happy'], 
    ['brown', 'two-eyes', 'angry'], 
    ['brown', 'two-eyes', 'happy'], 
    ['blue', 'single-eye', 'angry'], 
    ['blue', 'single-eye', 'happy'], 
    ['blue', 'two-eyes', 'angry'], 
    ['blue', 'two-eyes', 'happy'] 
] 

これは私が立ち往生した場所です。私は動的に生成された配列を.filter()内に統合し、||を使用する方法を理解できないようです。それに応じて& &。

ご協力いただきまして誠にありがとうございます。

+0

ない結果が期待したもの、ありますか?質問に入力配列を含めることはできますか? – guest271314

答えて

3

他の回答の両方が右に見えます。既に提案されていることに加えて、関数が各行の長さに依存しないように、Array.everyも使用します。

const cart = [ 
    ['brown', 'single-eye', 'angry'], 
    ['brown', 'single-eye', 'happy'], 
    ['brown', 'two-eyes', 'angry'], 
    ['brown', 'two-eyes', 'happy'], 
    ['blue', 'single-eye', 'angry'], 
    ['blue', 'single-eye', 'happy'], 
    ['blue', 'two-eyes', 'angry'], 
    ['blue', 'two-eyes', 'happy'] 
    ]; 

const filteredProducts = allProducts.filter((a) => { 
    const prodTags = a.tags; 

    return cart.some((row) => { 
    return row.every((element) => { 
     return prodTags.includes(element); 
    }); 
    }); 
}); 
+0

良い提案。 –

+0

恐ろしい!行の長さに依存しない関数は、まさに私が探していたものです!小さな改善をありがとう、オリジナルソリューションのために@RickHitchcockに感謝します。あなたは素晴らしいです! – popshuvit

2

あなたは条件の少なくとも一方が満たされていることを確認するために、デカルト積アレイ上Array.prototype.some()を使用することができます。

const filteredProducts = allProducts.filter((a) => { 
    const prodTags = a.tags, 
     cart = [ 
       ['brown', 'single-eye', 'angry'], 
       ['brown', 'single-eye', 'happy'], 
       ['brown', 'two-eyes', 'angry'], 
       ['brown', 'two-eyes', 'happy'], 
       ['blue', 'single-eye', 'angry'], 
       ['blue', 'single-eye', 'happy'], 
       ['blue', 'two-eyes', 'angry'], 
       ['blue', 'two-eyes', 'happy'] 
       ]; 

    return cart.some((e) => { 
    return progTags.includes(e[0]) && progTags.includes(e[1]) && progTags.includes(e[2]); 
    }); 
}); 
0

trueが生じた場合に予想される生成ロジックは、あなたの配列で、任意の特定の行を意味し、計算する必要がある最後の行になります。私のアプローチは、特定の行がtrueを返したときにブレークするforループを実行することです。 trueには、行の結果は、falseにフォールバックしない場合:

var filtersArray = [ 
    ['brown', 'single-eye', 'angry'], 
    ['brown', 'single-eye', 'happy'], 
    ['brown', 'two-eyes', 'angry'], 
    ['brown', 'two-eyes', 'happy'], 
    ['blue', 'single-eye', 'angry'], 
    ['blue', 'single-eye', 'happy'], 
    ['blue', 'two-eyes', 'angry'], 
    ['blue', 'two-eyes', 'happy'] 
]; 


const filteredProducts = allProducts.filter((a) => { 
    // return brown or blue products in with omnis tag 
    const prodTags = a.tags; 

    for (var i = 0; i < filtersArray.length; i++) { 
    let color = filtersArray[i][0]; 
    let count = filtersArray[i][1]; 
    let emotion = filtersArray[i][2]; 

    if (prodTags.includes(color) && prodTags.includes(count) && prodTags.includes(emotion)) { 
     return true; 
    } 
    } 

    return false; 
)}; 
0

グループ化された項目を持つ配列を使用して、チェックを繰り返します。

var allProducts = [{ foo: 1, tags: ['abc', 'def'] }, { foo: 2, tags: ['blue', 'two-eyes', 'happy'] }], 
 
    groups = [['brown', 'blue'], ['single-eye', 'two-eyes'], ['angry', 'happy']], 
 
    filteredProducts = allProducts.filter(product => groups.every(group => group.some(item => product.tags.includes(item)))); 
 

 
console.log(filteredProducts);
.as-console-wrapper { max-height: 100% !important; top: 0; }

関連する問題