【发布时间】:2021-04-19 03:38:48
【问题描述】:
作为this question 的更正版本重新发布。我已经查看了this,但它并没有帮助我处理未知的数组嵌套。
编辑:添加了有关为什么 Lodash _.get 不起作用的信息。这是Stackblitz。有一个 npm 库,Object-Scan 可以工作——但是,我无法让 Angular 很好地使用那个包。
这适用于 Angular 应用程序中的列渲染器组件。用户选择要显示的列,该列将映射到它的任何位置。因此,在下面的示例中,如果用户选择显示“类别”,并将其映射到“兴趣 [类别]”,则该函数需要在数据中查找与该映射对应的值。
样本数据:
const response = {
id: "1234",
version: "0.1",
drinks: ["Scotch"],
interests: [
{
categories: ["baseball", "football"],
refreshments: {
drinks: ["beer", "soft drink"]
}
},
{
categories: ["movies", "books"],
refreshments: {
drinks: ["coffee", "tea", "soft drink"]
}
}
],
goals: [
{
maxCalories: {
drinks: "350",
pizza: "700"
}
}
]
};
对于这些数据,可能的映射是:
id,
version,
drinks,
interests[categories],
interests[refreshments][drinks],
goals[maxCalories][drinks],
goals[maxCalories][pizza],
要求:
我需要一个可以在 Angular 中工作的递归函数,并接受两个参数:一个用于数据对象response,第二个选择器映射字符串将返回适用的、可能嵌套的值,遍历任何对象和/或遇到的数组。映射字符串可能有点或括号表示法。可读的、自记录的代码是非常需要的。
例如,基于上面的数据对象:
-
getValues("id", response);应该返回["1234"] -
getValues("version", response);应该返回["0.1"] -
getValues("drinks", response);应该返回["Scotch"] -
getValues("interests.categories", response)应该返回["baseball", "football", "movies", "books"] -
getValues("interests[refreshments][drinks]", response);应该返回["beer", "soft drink", "coffee", "tea", "soft drink" ],因为interests数组中可能有许多项目。 -
getValues("goals.maxCalories.drinks", response);应该返回["350"]
返回的值最终将被删除和排序。
原函数:
function getValues(mapping, row) {
let rtnValue = mapping
.replace(/\]/g, "")
.split("[")
.map(item => item.split("."))
.reduce((arr, next) => [...arr, ...next], [])
.reduce((obj, key) => obj && obj[key], row)
.sort();
rtnValue = [...new Set(rtnValue)]; //dedupe the return values
return rtnValue.join(", ");
}
上面的工作正常,就像 Lodash 的 get: 如果你通过,例如:"interests[0][refreshments][drinks],它工作得很好。但是,映射不知道嵌套数组,并简单地传入"interests[refreshments][drinks]",从而导致undefined。任何后续的数组项都必须考虑在内。
【问题讨论】:
-
看来您基本上是在寻找实现 Lodash 的 get function
-
没有。请参阅我在帖子中添加的说明。
-
getValues("interests[refreshments][drinks]", response);无效。索引元素只能是数字或带引号的字符串。 -
你是对的,但这是从数据库返回并传递给函数的字符串。因此,在最初的问题中,
replace.split.map.reduce方法的舞蹈将输入字符串转换为更可接受的内容:["interests", "refreshments", "drinks"]在下面的答案中,这在单行中处理得更加优雅:query.split (/[[\].]+/g).filter (Boolean) -
仍然需要将对象扫描迁移到打字稿,以便 Angular 可以处理它......一旦我得到它可能会在这里发布
标签: javascript arrays angular recursion nested