2017-11-25 7 views
0

JS配列のuser-company-rolesオブジェクトに対して柔軟なテーブルフィルタを作成したいと思います。ユーザは、マッチングの際にAND(& &)オペランドを使用して、複数の値を用いて複数のオブジェクトプロパティに対してフィルタリングを提供することができなければならない。複数のプロパティと複数の値でネストされた配列をフィルタリングする

ここでロジックを実装する方法についてのヒントをいただきたいと思います。もちろん、私は配列をループすることができ、複数のネストされたif文を持つことができますが、おそらくもっとクリーンでいいアプローチがありますか?

ユーザー社-ロールアレイIは(フィルタがこのようにユーザがオブジェクトに一致する配列をフィルタリングする場合 マッチング

const userArray = [ 
{ 
    "id": "peterpan", 
    "name": "Peter pan", 
    "company": [ 
     { 
      "id": "12345678", 
      "name": "Company A", 
      "roles": [ 
       "Role A", 
       "Role B", 
       "Role C" 
      ] 
     } 
    ], 
    "systemRoles": [ 
     { 
      "systemName": "System A", 
      "role": "Admin" 
     }, 
     { 
      "systemName": "System B", 
      "role": "User" 
     } 
    ] 
}, 
{ 
    "id": "robinhood", 
    "name": "Robin Hood", 
    "company": [ 
     { 
      "id": "9876543", 
      "name": "Company B", 
      "roles": [ 
       "Role A" 
      ] 
     }, 
     { 
      "id": "546372", 
      "name": "Company C", 
      "roles": [ 
       "Role A" 
      ] 
     } 
    ], 
    "systemRoles": [ 
     { 
      "systemName": "System B", 
      "role": "User" 
     } 
    ] 
}, 
{ 
    "id": "biggiant", 
    "name": "Big Giant", 
    "company": [ 
     { 
      "id": "546372", 
      "name": "Company C", 
      "roles": [ 
       "Role A" 
      ] 
     } 
    ], 
    "systemRoles": [ 
     { 
      "systemName": "System B", 
      "role": "User" 
     } 
    ] 
} 
]; 

フィルタオブジェクト

const filter = { 
     includeUserIds: [], // filters 'user.id' that matches values in this array 
     includeCompanyNames: [], // filters 'user.company.name' that matches values in this array 
     includeSystemRoleNames: [], // filters 'user.systemRoles.role' that matches values in this array 
     includeCompanyRoles: [], // filters 'user.company.roles' that matches values in this array 
     excludeSystemRoleNames: [], // filters 'user.systemRoles.role' that **DOES NOT** match values in this array 
     excludeCompanyRoles: [] // filters 'user.company.roles' that **DOES NOT** match values in this array 
    } 

擬似コード):

filter.includeUserIds && filter.includeCompanyNames 
    && filter.includeSystemRoleNames && filter.includeCompanyRoles 
    && !filter.excludeSystemRoleNames && !filter.excludeCompanyRoles 

例1:ユーザーIDによるフィルタユーザー:

const filter = { 
     includeUserIds: ['peterpan', 'robinhood'], 
     includeCompanyNames: [], 
     includeSystemRoleNames: [], 
     includeCompanyRoles: [], 
     excludeSystemRoleNames: [], 
     excludeCompanyRoles: [] 
    } 

ピーターパンとロビン・フッドのユーザーとの配列を返します

例2:会社名でフィルタ

const filter = { 
     includeUserIds: [], 
     includeCompanyNames: ['Company C'], 
     includeSystemRoleNames: [], 
     includeCompanyRoles: [], 
     excludeSystemRoleNames: [], 
     excludeCompanyRoles: [] 
    } 

ロビンフッドとビッグジャイアントのユーザーで配列を返します

例3:会社の役割とシステムの役割

const filter = { 
     includeUserIds: [], 
     includeCompanyNames: [], 
     includeSystemRoleNames: ['User'], 
     includeCompanyRoles: ['Role A'], 
     excludeSystemRoleNames: ['Admin'], 
     excludeCompanyRoles: [] 
    } 

によるフィルタはロビン・フッドとビッグジャイアントユーザーとの配列を返します

答えて

1

私は、フィルタの種類ごとに決定関数を作成しますと、 filterと同じ特性を持つオブジェクトに入れます。各関数は、itemタイプanyfilterタイプstring[]の2つの引数を受け入れる必要があります。だから、次のようになります。おかげで

const filtered = userArray.filter(user => { 
    let include = true; 
    Object.keys(deciders).forEach(type => include &= deciders[type](user, filter[type])); 
    return include; 
}); 
+0

:次にフィルタリング

const deciders = { includeUserIds: (item, filter) => { ... }, includeCompanyNames: (item, filter) => { ... }, includeSystemRoleNames: (item, filter) => { ... }, includeCompanyRoles: (item, filter) => { ... }, excludeSystemRoleNames: (item, filter) => { ... }, excludeCompanyRoles: (item, filter) => { ... }, }; 

のように元の配列の簡単なfilterです。 1つのdeciders関数内で論理の例を挙げることはできますか? –

+1

基本的にそれは単純な '(item、filter)=> filter.indexOf(item)!== -1'ですが、例えば。あなたが実際の価値がより深い「会社」の場合 – Flying

関連する問題