如何翻转嵌套的数组/对象结构并按最低对象重新命名键?

4

我有可用的lodash 4.17

我有以下API响应结构:

{
    "things": [
        {
            "id": 14500,
            "name": "Q1 Out Ind",
            "thing_type_id": 6,
            "owner_id": 1680,
            "owner": {
                "id": 1680,
                "model_id": 602
            },
            "thing_type": {
                "id": 6,
                "name": "The Type of Thing"
            },
            "related_things": [
                {
                    "id": 9749,
                    "name": "unnamed thing",
                    "thing_id": 14500,
                    "more_things": [
                        {
                            "id": 16166,
                            "name": "Num Thing Sum",
                            "datasource_object_id": 9408,
                            "thing_id": 9749,
                            "external_datasource": {
                                "id": 9408,
                                "parent_id": 2810,
                                "target_id": 15028
                            }
                        }
                    ]
                }
            ]
        },
        {
            "id": 14503,
            "name": "Q2 Out Ind",
            "thing_type_id": 6,
            "owner_id": 1681,
            "owner": {
                "id": 1681,
                "model_id": 602
            },
            "thing_type": {
                "id": 6,
                "name": "The Type of Thing"
            },
            "related_things": [
                {
                    "id": 9750,
                    "name": "unnamed thing2",
                    "thing_id": 14503,
                    "more_things": [
                        {
                            "id": 16167,
                            "name": "Num Thing Avg",
                            "datasource_object_id": 9409,
                            "thing_id": 9750,
                            "external_datasource": {
                                "id": 9409,
                                "parent_id": 2810,
                                "target_id": 15029
                            }
                        },
                        {
                            "id": 16168,
                            "name": "Num Thing Count",
                            "datasource_object_id": 9408,
                            "thing_id": 9750,
                            "external_datasource": {
                                "id": 9408,
                                "parent_id": 2810,
                                "target_id": 15028
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

我正在尝试获取匹配特定target_id的对象列表,这些对象位于嵌套结构的最末端。

到目前为止,以下代码仅在数组中有一个结果时有效:

_.filter(things.things, 
      function (obj) {
        return obj.related_things[0].more_things[0].external_datasource.target_id == 15028;
      }
  )

然而,正如您在此示例中所看到的,在这种情况下,它在末尾有两个“things”,因为more_thingsrelated_things都有一个数组,所以存在匹配 - 我该如何调整我的lodash过滤器以跨任何深度搜索?我需要一个匹配对象列表,以显示与匹配目标相关的UI属性。

你需要some。顺便问一下,你是需要整个大的东西返回还是只需要带有external_datasource字段的小对象? - cmgchess
我需要整个东西返回,因为父级包含我需要显示的属性。现在看一下 some - Carmageddon
@cmgchess 我已经阅读了“some”文档,但仍不清楚如何将其应用到我的初始解决方案中,以代替硬编码的“[0]”。 - Carmageddon
只有一个目标ID匹配的项目。还有一个问题ID匹配的项目。 - James
@James 抱歉!已经修改了,应该是 target_id :) - Carmageddon
更新了一遍,现在应该没问题了。抱歉。 - Carmageddon
2个回答

1

你可以在 filter 内部嵌套 _some 函数。顺便说一句,这也适用于原生数组的 filtersome

const things = {    "things": [        {            "id": 14500,            "name": "Q1 Out Ind",            "thing_type_id": 6,            "owner_id": 1680,            "owner": {                "id": 1680,                "model_id": 602            },            "thing_type": {                "id": 6,                "name": "The Type of Thing"            },            "related_things": [                {                    "id": 9749,                    "name": "unnamed thing",                    "thing_id": 14500,                    "more_things": [                        {                            "id": 16166,                            "name": "Num Thing Sum",                            "datasource_object_id": 9408,                            "thing_id": 9749,                            "external_datasource": {                                "id": 9408,                                "parent_id": 2810,                                "target_id": 15028                            }                        }                    ]                }            ]        },        {            "id": 14503,            "name": "Q2 Out Ind",            "thing_type_id": 6,            "owner_id": 1681,            "owner": {                "id": 1681,                "model_id": 602            },            "thing_type": {                "id": 6,                "name": "The Type of Thing"            },            "related_things": [                {                    "id": 9750,                    "name": "unnamed thing2",                    "thing_id": 14503,                    "more_things": [                        {                            "id": 16167,                            "name": "Num Thing Avg",                            "datasource_object_id": 9409,                            "thing_id": 9750,                            "external_datasource": {                                "id": 9409,                                "parent_id": 2810,                                "target_id": 15029                            }                        },                        {                            "id": 16168,                            "name": "Num Thing Count",                            "datasource_object_id": 9408,                            "thing_id": 9750,                            "external_datasource": {                                "id": 9408,                                "form_id": 2810,                                "target_id": 15028                            }                        }                    ]                }            ]        }    ]}

const id = 15028

const res = _.filter(things.things, a => {
  return _.some(a.related_things, b => {
    return _.some(b.more_things, c => c.external_datasource.target_id === id)
  })
})

console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

没有使用 lodash

const things = {    "things": [        {            "id": 14500,            "name": "Q1 Out Ind",            "thing_type_id": 6,            "owner_id": 1680,            "owner": {                "id": 1680,                "model_id": 602            },            "thing_type": {                "id": 6,                "name": "The Type of Thing"            },            "related_things": [                {                    "id": 9749,                    "name": "unnamed thing",                    "thing_id": 14500,                    "more_things": [                        {                            "id": 16166,                            "name": "Num Thing Sum",                            "datasource_object_id": 9408,                            "thing_id": 9749,                            "external_datasource": {                                "id": 9408,                                "parent_id": 2810,                                "target_id": 15028                            }                        }                    ]                }            ]        },        {            "id": 14503,            "name": "Q2 Out Ind",            "thing_type_id": 6,            "owner_id": 1681,            "owner": {                "id": 1681,                "model_id": 602            },            "thing_type": {                "id": 6,                "name": "The Type of Thing"            },            "related_things": [                {                    "id": 9750,                    "name": "unnamed thing2",                    "thing_id": 14503,                    "more_things": [                        {                            "id": 16167,                            "name": "Num Thing Avg",                            "datasource_object_id": 9409,                            "thing_id": 9750,                            "external_datasource": {                                "id": 9409,                                "parent_id": 2810,                                "target_id": 15029                            }                        },                        {                            "id": 16168,                            "name": "Num Thing Count",                            "datasource_object_id": 9408,                            "thing_id": 9750,                            "external_datasource": {                                "id": 9408,                                "form_id": 2810,                                "target_id": 15028                            }                        }                    ]                }            ]        }    ]}

const id = 15028

const res = things.things.filter(a => {
  return a.related_things.some(b => {
    return b.more_things.some(c => c.external_datasource.target_id === id)
  })
})

console.log(res)


1
可以了,我现在明白怎么做了,谢谢! - Carmageddon
1
@Carmageddon 这是 O(n^3) 的,但无法改变。 - cmgchess
是的,这正是我选择在客户端而不是服务器端执行此操作的原因 :) - Carmageddon

0
你可以在使用filter时,结合flatMapsome

const things= {
    "things": [

   {
        "id": 1450033333,
        "name": "SHOULD NOT BE IN THE RESULTS",
        "thing_type_id": 6,
        "owner_id": 1680,
        "owner": {
            "id": 1680,
            "model_id": 602
        },
        "thing_type": {
            "id": 6,
            "name": "The Type of Thing"
        },
        "related_things": [
            {
                "id": 9749,
                "name": "unnamed thing",
                "thing_id": 14500,
                "more_things": [
                    {
                        "id": 16166,
                        "name": "Num Thing Sum",
                        "datasource_object_id": 9408,
                        "thing_id": 9749,
                        "external_datasource": {
                            "id": 9408,
                            "parent_id": 2810,
                            "target_id": 15024
                        }
                    }
                ]
            }
        ]
    },
   
        {
            "id": 14500,
            "name": "Q1 Out Ind",
            "thing_type_id": 6,
            "owner_id": 1680,
            "owner": {
                "id": 1680,
                "model_id": 602
            },
            "thing_type": {
                "id": 6,
                "name": "The Type of Thing"
            },
            "related_things": [
                {
                    "id": 9749,
                    "name": "unnamed thing",
                    "thing_id": 14500,
                    "more_things": [
                        {
                            "id": 16166,
                            "name": "Num Thing Sum",
                            "datasource_object_id": 9408,
                            "thing_id": 9749,
                            "external_datasource": {
                                "id": 9408,
                                "parent_id": 2810,
                                "target_id": 15028
                            }
                        }
                    ]
                }
            ]
        },
        {
            "id": 14503,
            "name": "Q2 Out Ind",
            "thing_type_id": 6,
            "owner_id": 1681,
            "owner": {
                "id": 1681,
                "model_id": 602
            },
            "thing_type": {
                "id": 6,
                "name": "The Type of Thing"
            },
            "related_things": [
                {
                    "id": 9750,
                    "name": "unnamed thing2",
                    "thing_id": 14503,
                    "more_things": [
                        {
                            "id": 16167,
                            "name": "Num Thing Avg",
                            "datasource_object_id": 9409,
                            "thing_id": 9750,
                            "external_datasource": {
                                "id": 9409,
                                "parent_id": 2810,
                                "target_id": 15029
                            }
                        },
                        {
                            "id": 16168,
                            "name": "Num Thing Count",
                            "datasource_object_id": 9408,
                            "thing_id": 9750,
                            "external_datasource": {
                                "id": 9408,
                                "parent_id": 2810,
                                "target_id": 15028
                            }
                        }
                    ]
                }
            ]
        }
    ]
}


const results = _.filter(things.things, thing => {
  const relatedThings = _.flatMap(thing.related_things, 'more_things');
  return _.some(relatedThings, moreThing => moreThing.external_datasource.target_id == 15028);
});
console.log(results)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>


谢谢,我觉得@cmgchess的解决方案更具描述性和易于理解其目的。 - Carmageddon

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