根据 JavaScript 中嵌套 JSON 数组对象的值过滤/删除数组对象

问题描述 投票:0回答:1

我有一个适用于 REST 响应的过滤条件。此响应具有嵌套的子对象。任务和过滤器函数中的 For 循环不适用于嵌套数组对象。请帮我根据 body.items[index].details.items[index].Id 值过滤下面的 JSON 数组对象。

所以在这里我希望只保留 body.items.details.items 中与 300100619883728 匹配的数组。

JSON:

{
    "error": null,
    "message": {
      "summary": ""
    },
    "status": 200,
    "headers": {},
    "body": {
      "items": [
        {
          "Name": "Test1",
          "LastName": "ABC",
          "details": {
            "items": [
              {
                "Id": "300100619883728",
                "Status": "Draft",
                "subDetails": {
                  "items": [
                    {
                      "CurrentAddress": "Some address"
                    }
                  ],
                  "totalResults": 1,
                  "count": 1,
                  "hasMore": false,
                  "limit": 25,
                  "offset": 0
                }
              },
              {
                "Id": "300100619883738",
                "Status": "Draft",
                "subDetails": {
                  "items": [
                    {
                      "CurrentAddress": "Some Address"
                    }
                  ],
                  "totalResults": 1,
                  "count": 1,
                  "hasMore": false,
                  "limit": 25,
                  "offset": 0
                }
              }
            ],
            "totalResults": 2,
            "count": 2,
            "hasMore": false,
            "limit": 25,
            "offset": 0
          }
        },
        {
          "Name": "Test2",
          "LastName": "ABC",
          "details": {
            "items": [
              {
                "Id": "300100619883728",
                "Status": "Draft",
                "subDetails": {
                  "items": [
                    {
                      "CurrentAddress": "Some address"
                    }
                  ],
                  "totalResults": 1,
                  "count": 1,
                  "hasMore": false,
                  "limit": 25,
                  "offset": 0
                }
              },
              {
                "Id": "300100619883739",
                "Status": "Draft",
                "subDetails": {
                  "items": [
                    {
                      "CurrentAddress": "Some Address"
                    }
                  ],
                  "totalResults": 1,
                  "count": 1,
                  "hasMore": false,
                  "limit": 25,
                  "offset": 0
                }
              }
            ],
            "totalResults": 2,
            "count": 2,
            "hasMore": false,
            "limit": 25,
            "offset": 0
          }
        }
      ],
      "totalResults": 2
    },
    "ok": true,
    "statusText": "OK"
  }

在数组结构不变的情况下,过滤后的预期结果为:

{
    "error": null,
    "message": {
      "summary": ""
    },
    "status": 200,
    "headers": {},
    "body": {
      "items": [
        {
          "Name": "Test1",
          "LastName": "ABC",
          "details": {
            "items": [
              {
                "Id": "300100619883728",
                "Status": "Draft",
                "subDetails": {
                  "items": [
                    {
                      "CurrentAddress": "Some address"
                    }
                  ],
                  "totalResults": 1,
                  "count": 1,
                  "hasMore": false,
                  "limit": 25,
                  "offset": 0
                }
              }
            ],
            "totalResults": 2,
            "count": 2,
            "hasMore": false,
            "limit": 25,
            "offset": 0
          }
        },
        {
          "Name": "Test2",
          "LastName": "ABC",
          "details": {
            "items": [
              {
                "Id": "300100619883728",
                "Status": "Draft",
                "subDetails": {
                  "items": [
                    {
                      "CurrentAddress": "Some address"
                    }
                  ],
                  "totalResults": 1,
                  "count": 1,
                  "hasMore": false,
                  "limit": 25,
                  "offset": 0
                }
              }
            ],
            "totalResults": 2,
            "count": 2,
            "hasMore": false,
            "limit": 25,
            "offset": 0
          }
        }
      ],
      "totalResults": 2
    },
    "ok": true,
    "statusText": "OK"
  }

filter 我试图获得所需的结果,但无法转到嵌套对象来访问其值和过滤器。

const filteredObj = obj.body.items.filter(function (item) {
   return item.details.items == 300100619883728;
});
javascript arrays json filter nested
1个回答
0
投票

您打算做的事情并不像看起来那么简单:您不想过滤单个数组,而是过滤多个数组(

details.items
),每个数组都是属于更高数组(
body.items
)成员的内部对象.

如果您不介意改变原始响应(这通常不是一个好的做法),下面的代码行就可以解决问题。

response.body.items.forEach(item => item.details.items = item.details.items.filter(item => item.Id === ID_TO_FIND));

但是,更干净的解决方案是创建一个新的

body.items
,其中每个
item
details.items
都被过滤。这是它的工作原理:

const ID_TO_FIND = "300100619883728"; // The id we want to keep

// The map() function creates a new copy of an array,
// while allowing us to change how each element in that copy looks like
const fileterdBodyItems = response.body.items.map(item => { 
  // For each item in the body, we create a filtered copy of that item's details
  const fileterdDetailsItems = item.details.items.filter(item => item.Id === ID_TO_FIND)
  // Now, we create a new details object for that item, which uses all the original
  // attributes of the original details, except for items; we replace them with 
  // fileterdDetailsItems 
  const fileterdDetails = { ...item.details, items: fileterdDetailsItems };

  // Like the above, we want the filtered item to contain all the original
  // attributes of the original item, except for details, replacing them with
  // filtered details
  const filteredItem = { ...item, details: fileterdDetails };

  // Each object returned from the map() function's callback will become one
  // element in fileterdBodyItems
  return filteredItem ;
});

// This should be familiar by now
const fileterdBody = {...response.body, items: fileterdBodyItems};
const filteredResponse = {...response, body: fileterdBody}
© www.soinside.com 2019 - 2024. All rights reserved.