JavaScript数组.filter通过子元素筛选

4

我有一个对象数组(客户端),格式如下:

"{"client_id":"AAA1","contracts":[{"contract_id":"CON1-AAA1","revisions":[{"date":"2018-07-30","status":"First Sign"}]}]}"

我可以轻松按client_id过滤:

var query = clients.filter(x => x.client_id == "AAA1");

然而,我希望能够按修订日期或状态进行过滤。我尝试了以下操作,但是遇到了错误“未捕获的类型错误:无法读取未定义属性的状态”。

var query = clients.filter(x => x.contracts.revisions.status == "First Sign");

这种方式可行吗?还是我想太多了? :)

"{"client_id":"AAA1","contracts":[{"contract_id":"CON1-AAA1","revisions":[{"date":"2018-07-30","status":"First Sign"}]}]}" 不是一个数组,而是一个字符串。请使用 <> 按钮提供一个 [mcve]。 - mplungjan
@korocota,请提供正确的JSON格式! - Prashant Pimpale
4个回答

9
您可以通过使用 Array#filter 和两个 Array#some 的组合来实现这一点:

const clients = [{
  "client_id": "AAA1",
  "contracts": [{
    "contract_id": "CON1-AAA1",
    "revisions": [{
      "date": "2018-07-30",
      "status": "First Sign"
    }]
  }]
}, {
  "client_id": "AAA2",
  "contracts": [{
    "contract_id": "CON1-AAA2",
    "revisions": [{
      "date": "2018-08-30",
      "status": "Second Sign"
    }]
  }]
}];

let result = clients.filter(cl => cl.contracts.some(c => c.revisions.some(r => r.status == 'First Sign')));
console.log(result);


OP 可能想要过滤 clients,而不是 contracts - Adelin

0

这是因为修订和合同是一个数组。

您需要在任何项目等于所有项目等于之间进行选择。

使用Array.prototype.some - 数组中的任何项目都符合某个标准。
使用Array.prototype.every - 数组中的所有项目都符合某个标准。

查找至少有一个修订状态为“First Sign”的合同的客户示例:

const query = clients.filter(x => x.contracts.some(c => c.revisions.some(r => r.status == "First Sign")));

"contracts" 也是一个数组。 - barbsan
x.contracts.revisions 但是 revisions 不是 contracts 的属性,contracts 是一个数组。 - CertainPerformance
是的,我没注意到。我已经修正了我的回答。 - Amir Popovich
客户端是一个带有标识符和合同数组的对象,每个合同都有一个带有修订版本数组的标识符,每个修订版本都有一个日期和状态,如果这有意义的话。 - korocota

0

可以像下面这样使用filtersome

var clients = [
{
    "client_id": "AAA1",
    "contracts": [
    {
        "contract_id": "CON1-AAA1",
        "revisions": [
        {
            "date": "2018-07-30",
            "status": "First Sign"
        }]
    }]
},
{
    "client_id": "AAA1",
    "contracts": [
    {
        "contract_id": "CON1-AAA1",
        "revisions": [
        {
            "date": "2018-07-30",
            "status": "Second Sign"
        }]
    }]
}]

var query = clients.filter(
    x => x.contracts.some(y => y.revisions.some(z => z.status == "First Sign")));

console.log(query);


0

所以,由于您的错误消息和问题描述清楚地表明您发布的字符串(看起来像一个对象)实际上是一个更大的数组的摘录,因此您可以执行以下操作

const arr = [{"client_id":"AAA1","contracts":[{"contract_id":"CON1-AAA1","revisions":[{"date":"2018-07-30","status":"First Sign"}]}]}];
const res = arr.filter(client => client.contracts.some(contract => contract.revisions.some(revision => revision.status === 'First Sign')));

console.log(res);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接