匹配两个数组中的值并返回过滤后的数组的数组方法

时间:2018-11-30 21:01:55

标签: javascript arrays

我正在尝试确定要获取MongoDB集合中所需数据的.filter或.some的哪种组合。

首先,我有一个docs数组,如下所示:

let docs = [
 { _id: '5ba39a12179b771820413ad8',
  branches:
   [ { _id: '3nc26645121f0613be08167r', name: 'New York' },
     { _id: '3fc26645121f0613be08185d', name: 'Los Angeles' },
     { _id: '2hc26648121f0613be081862', name: 'Seattle' },
     { _id: '7jc2664a121f0613be081869', name: 'Chicago' },
     { _id: '7ju2664a121f0613be08186e', name: 'Charlotte' } ],
  updatedAt: '2018-09-20T13:01:06.709Z',
  createdAt: '2018-09-20T13:01:06.709Z' },
{ _id: '3ya39a12179b771820413af5',
  branches:
   [ { _id: '3nc26645121f0613be08167r', name: 'New York' },
     { _id: '5ac26645121f0613be08145d', name: 'Miami' },
     { _id: '5ac2664a121f0613be08154s', name: 'Sacramento' } ],
  updatedAt: '2018-09-20T13:01:06.709Z',
  createdAt: '2018-09-20T13:01:06.709Z' 
 },
{ _id: '2sa39a12179b771820413gy4',
  branches:
   [ { _id: '1rd26645121d5613be08167h', name: 'Denver' },
     { _id: '5ac2664a121f0613be08154s', name: 'Sacramento' } ],
  updatedAt: '2018-09-20T13:01:06.709Z',
  createdAt: '2018-09-20T13:01:06.709Z' 
 }
];

我有一个传入的用户值数组,它们是ID,看起来像这样:

 let filterValues = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"];

现在我要编写的查询将返回一个新的docs数组,该数组仅包含filterValues数组中的ID与{内的ID之间具有匹配项的文档每个文档根目录上的{1}}属性(它是一个数组)。

在我在此处提供的示例中,结果数组应包含原始branches数组的3个文档中的2个-具体来说,前两个文档是因为它们都包含至少一个ID在各自的docs数组中传递-从我的文档数据分配给Charlotte和Miami的ID。

有没有一种方法可以使用branches.filter.includes或某种组合来编写?

为清楚起见,最终的过滤结果应如下所示:

.some

4 个答案:

答案 0 :(得分:3)

 const result =  array.filter(({ branches }) => branches.some(({ _id }) => filterValues.includes(_id)))

如果您只是按照自己的想法去做,那该怎么办。

答案 1 :(得分:1)

奇怪的是,由于您已经提出了应该使用的工具,因此您自己还没有实现这一点……差不多了。

首先,您需要根据条件获取docs的子集,以及为此目的设计的.filter,因此

var filteredDocs = docs.filter(doc =>
    // here we need an expression of whether the doc.branches contains an id from filterValues
)

接下来,您必须确定.branches的{​​{1}}中是否有doc的ID,filterValues是一个数组,所以.branches在这里合适:

.some

最后,您需要检查var filteredDocs = docs.filter(doc => doc.branches.some(branch => // here an expression should check whether branch._id is among filterValues ) ) 是否在branch._id中,最简单的方法是使用filterValues(也可以使用.includes,但是因为id是唯一的,所以没有意义。

.some

您可以将它用作单行代码,这有点难以理解:

var filteredDocs = docs.filter(doc =>
    doc.branches.some(branch =>
        filterValues.includes(branch._id)
    )
)

在控制台中尝试此操作将向您显示结果(请注意,var filteredDocs = docs.filter(doc => doc.branches.some(branch => filterValues.includes(branch._id))) 的发布语法中不正确):

docs

答案 2 :(得分:1)

以下是您要执行的操作的可行示例:

const data = [{ _id: "5ba39a12179b771820413ad8", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "3fc26645121f0613be08185d", name: 'Los Angeles' }, { _id: "2hc26648121f0613be081862", name: 'Seattle' }, { _id: "7jc2664a121f0613be081869", name: 'Chicago' }, { _id: "7ju2664a121f0613be08186e", name: 'Charlotte' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" }, { _id: "3ya39a12179b771820413af5", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "5ac26645121f0613be08145d", name: 'Miami' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " }, { _id: "2sa39a12179b771820413gy4", branches: [{ _id: "1rd26645121d5613be08167h", name: 'Denver' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " } ]
const vals = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"]

const result = data.filter(x => x.branches.some(y => vals.includes(y._id)))

console.log(result)

这是简短的ES6版本,主要在此处使用箭头功能等来简化内容。扩展为:

const data = [{ _id: "5ba39a12179b771820413ad8", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "3fc26645121f0613be08185d", name: 'Los Angeles' }, { _id: "2hc26648121f0613be081862", name: 'Seattle' }, { _id: "7jc2664a121f0613be081869", name: 'Chicago' }, { _id: "7ju2664a121f0613be08186e", name: 'Charlotte' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" }, { _id: "3ya39a12179b771820413af5", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "5ac26645121f0613be08145d", name: 'Miami' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " }, { _id: "2sa39a12179b771820413gy4", branches: [{ _id: "1rd26645121d5613be08167h", name: 'Denver' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " } ]
const vals = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"]

const result = data.filter(function(obj) {
  return obj.branches.some(function(branch) {
    return vals.includes(branch._id)
  })
})

console.log(result)

基本上,您首先要filter主数组(通过Array.filter),在内部使用Array.some,它会检查是否包含任何branches _id (通过Array.include)在filter数组中。就这么简单。

答案 3 :(得分:1)

let docs = [{ _id: "5ba39a12179b771820413ad8", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "3fc26645121f0613be08185d", name: 'Los Angeles' }, { _id: "2hc26648121f0613be081862", name: 'Seattle' }, { _id: "7jc2664a121f0613be081869", name: 'Chicago' }, { _id: "7ju2664a121f0613be08186e", name: 'Charlotte' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" }, { _id: "3ya39a12179b771820413af5", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "5ac26645121f0613be08145d", name: 'Miami' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " }, { _id: "2sa39a12179b771820413gy4", branches: [{ _id: "1rd26645121d5613be08167h", name: 'Denver' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " } ]
let filterValues = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"]

let result = [];
// For every items in docs
_.each(docs, item => {
  // Filter an item with filter values
  filterValues.forEach (value => {
    if (_.findWhere(item.branches, {_id: value})) {
      // Check and store it in the array
      result.push(item);
    }
  });
});
console.log(result);
<script src="https://fastcdn.org/Underscore.js/1.8.3/underscore-min.js"></script>