【问题标题】:Javascript array.filter by element in childrenJavascript array.filter by element in children
【发布时间】:2018-07-30 08:17:15
【问题描述】:

我有一个这样的对象(客户端)数组:

"{"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"}]}]}" 不是数组。它是一个字符串。请使用<> 按钮提供minimal reproducible example
  • @korocota 如果是,请提供正确的 JSON!

标签: javascript arrays filter children


【解决方案1】:

您可以通过使用 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 已编辑 ^^
  • @korocota 好吧,如果你不给他,他就不能投赞成票 :) 当前的 +1 来自我 :)
【解决方案2】:

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

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

使用Array.prototype.some - 数组中的任何项目都回答一个标准。
使用Array.prototype.every - 数组中的所有项目都回答了一个标准。

查找具有至少修订版且状态为“首次签署”的任何合同的客户的示例:

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

【讨论】:

  • contracts 也是一个数组
  • x.contracts.revisions 但是revisions 不是contracts 的属性,contracts 是一个数组
  • 是的,没注意到。我已经确定了答案。
  • 客户端是一个带有标识符和合约数组的对象,每个合约都有一个带有修订数组的标识符,每个修订都有一个日期和状态,如果有意义的话
【解决方案3】:

使用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);

【讨论】:

    【解决方案4】:

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

    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);

    【讨论】:

      猜你喜欢
      • 2022-12-01
      • 1970-01-01
      • 2022-12-01
      • 2020-02-05
      • 2020-08-25
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多