解析代码
const data = [
{
continent_name: "Asia",
country_name: "Iran",
subdivision_1_name: "Chaharmahal and Bakhtiari Province",
city_name: "Lir Abi"
},
{
continent_name: "Europe",
country_name: "Cyprus",
subdivision_1_name: "Ammochostos",
city_name: "Protaras"
},
{
continent_name: "Asia",
country_name: "Iran",
subdivision_1_name: "West Azerbaijan Province",
city_name: "Post"
},
{
continent_name: "Africa",
country_name: "Somalia",
subdivision_1_name: "Bakool",
city_name: "Oddur"
}
],
keys = ["continent_name", "country_name", "subdivision_1_name", "city_name"],
result = data.reduce(
(r, o) => {
keys.reduce(function (q, k) {
const label = o[k];
if (!q[label]) q._.push({ label, children: (q[label] = { _: [] })._ });
return q[label];
}, r);
return r;
},
{ _: [] }
)._;
最后一行是如何工作的 )._;
?
如果它返回[]
这个数组,那么为什么我的代码不起作用?
const numbers = [1,2,3,4,5];
const a = numbers.reduce((a, c) => a._ += c, { _: 5 })._;
我收到一个错误
无法在数字“6”上创建属性“_”
我将描述我是如何理解当前逻辑的。
TD;DR 简而言之
_
,这是reducer中生成的key,里面填充了原始数组的所有元素,即 反过来,基于数组keys
和相似键的联合进行分层嵌套。(在这种情况下,不是键本身,而是它们的值)我还改进了您的代码示例,在这种情况下,您需要考虑减速器箭头函数返回一个累加器,但您尝试返回一个没有
_
. 我所做的只是使用逗号运算符准确地返回累加器,为了让解析器不发誓,我将箭头函数的结果放在括号中。更多的:
我们看到
начального результата
一个属性_
等于空数组的对象在代码中作为 reducer 传递,如下所示:让我们称之为
RESULT
。结果会怎样
_
。首先,让我们确定它将是钥匙
r
(电池),让我提醒您这是相同的{ _: [] }
或RESULT
接下来,我们看到一个嵌套的 reducer,同样的
r
or再次通过 scope 传递给它RESULT
,但已经在名称下q
作为累加器的初始值。这个内部 reducer 负责将元素
data
转换为对象。该数组keys
用作此对象层次结构的规则。每个元素keys
都将嵌套在前一个元素中。如上所述,工作伴随着价值观。例如:
"continent_name"
这个текущийЭлементData['continent_name']
我们看到它是如何填充
_
的,如下所示:_.push(label, children:[])
条件检查从( ) to
if
的键值是否不存在,然后将包含子元素数组的元素推入键数组:keys
label
RESULT
_
label
children: (q[label] = { _: [] })._
(需要注意的是,这
_
不是我们要讨论的,而且我也不清楚它的目的,所以我不重点讨论它,但我相信_
它会更适合这里children
)这里发生的事情,如你所知,
q[label]
等于{ _: [] }
赋值操作返回赋值的结果,所以这是一个对象{ _: [] }
,然后我们通过 key 从中选择一个值_
,它是一个空数组。因此,在 条件下
if
,两件事同时发生_
中RESULT
RESULT
从值中按名称键入keys
内置减速器返回,
q[label]
即 嵌套属性q
而不是它本身q
(让我提醒您q
- 这就是r
属性相互嵌套的方式。最终
通过顶级键
"continent_name"
,嵌套对象形成相互嵌套(记住q[label]
),而这些对象又落入顶级键_
,最初是一个空数组。