在 lodash 中用 topairs 压平嵌套对象
flatten nested object with topairs in lodash
我有一个这样的对象:
let order={
"john":{
"hamburger":4
},
"alice":{
"pizza":10,
"milkshake":2
},
"bob":{
}
}
我想像这样展平:
let res=[
["john","hamburger",4],
["alice","pizza",4],
["alice","milkshake",4]
]
我知道如何使用 keyBy 反向执行此操作,但如何将它从递归对象转换为递归数组?
我尝试使用 toPairs,但我不知道如何使它递归
使用 _.toPairs()
得到一个 [name, items]
对的数组,你用 _.flatMap()
迭代它。从 items
对象中获取对,并使用 _.map()
创建包含信息的数组:
const { flatMap, toPairs, map } = _
const order = {"john":{"hamburger":4},"alice":{"pizza":10,"milkshake":2},"bob":{}}
const result = flatMap(
toPairs(order),
([name, items]) =>
map(
toPairs(items),
([product, price]) => [name, product, price]
)
)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
在原版 JS 中,您可以使用 Array.flatMap()
和 Object.entries()
来获得相同的结果:
const order = {"john":{"hamburger":4},"alice":{"pizza":10,"milkshake":2},"bob":{}}
const result = Object
.entries(order)
.flatMap(([name, items]) =>
Object.entries(items)
.map(([product, price]) => [name, product, price])
)
console.log(result)
此解决方案将以递归方式工作,并让您提供一个确定如何构建累加器的回调。请注意,它仅适用于对象,不适用于嵌套对象和数组的混合。
const flatten = (tree, acc, branch = [], build) =>
Object.entries(tree).reduce(
(a, [key, val]) =>
typeof val !== 'object'
? build(a, branch, key, val)
: flatten(val, a, branch.concat(key), build),
acc
);
在你的例子中,你希望分支是一个节点数组,最后一个叶子也在同一个数组中。
const source = {
a: {
b: {
c: 'c'
}
},
b: {
d: {
x: 'sdfdsgsf'
},
c: {
i: 'sdf',
f: {
one: {
two: {
three: 'deep'
}
}
}
}
}
};
const flatten = (tree, acc, branch = [], build) =>
Object.entries(tree).reduce(
(a, [key, val]) =>
typeof val !== 'object'
? build(a, branch, key, val)
: flatten(val, a, branch.concat(key), build),
acc
);
console.log(
flatten(source, [], [], (acc, branch, key, val) => [
...acc,
branch.concat(key, val)
])
);
产出
[
[ 'a', 'b', 'c', 'c' ],
[ 'b', 'd', 'x', 'sdfdsgsf' ],
[ 'b', 'c', 'i', 'sdf' ],
[
'b', 'c',
'f', 'one',
'two', 'three',
'deep'
]
]
我需要将分支节点连接成一个字符串,例如
{
'a.b.c.d': 'string',
'x.y.z': 'foo'
}
所以我用了
flatten(source, {}, [], (acc, branch, key, val) => ({
...acc,
[branch.concat(key).join('.')]: val
}))
我有一个这样的对象:
let order={
"john":{
"hamburger":4
},
"alice":{
"pizza":10,
"milkshake":2
},
"bob":{
}
}
我想像这样展平:
let res=[
["john","hamburger",4],
["alice","pizza",4],
["alice","milkshake",4]
]
我知道如何使用 keyBy 反向执行此操作,但如何将它从递归对象转换为递归数组? 我尝试使用 toPairs,但我不知道如何使它递归
使用 _.toPairs()
得到一个 [name, items]
对的数组,你用 _.flatMap()
迭代它。从 items
对象中获取对,并使用 _.map()
创建包含信息的数组:
const { flatMap, toPairs, map } = _
const order = {"john":{"hamburger":4},"alice":{"pizza":10,"milkshake":2},"bob":{}}
const result = flatMap(
toPairs(order),
([name, items]) =>
map(
toPairs(items),
([product, price]) => [name, product, price]
)
)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
在原版 JS 中,您可以使用 Array.flatMap()
和 Object.entries()
来获得相同的结果:
const order = {"john":{"hamburger":4},"alice":{"pizza":10,"milkshake":2},"bob":{}}
const result = Object
.entries(order)
.flatMap(([name, items]) =>
Object.entries(items)
.map(([product, price]) => [name, product, price])
)
console.log(result)
此解决方案将以递归方式工作,并让您提供一个确定如何构建累加器的回调。请注意,它仅适用于对象,不适用于嵌套对象和数组的混合。
const flatten = (tree, acc, branch = [], build) =>
Object.entries(tree).reduce(
(a, [key, val]) =>
typeof val !== 'object'
? build(a, branch, key, val)
: flatten(val, a, branch.concat(key), build),
acc
);
在你的例子中,你希望分支是一个节点数组,最后一个叶子也在同一个数组中。
const source = {
a: {
b: {
c: 'c'
}
},
b: {
d: {
x: 'sdfdsgsf'
},
c: {
i: 'sdf',
f: {
one: {
two: {
three: 'deep'
}
}
}
}
}
};
const flatten = (tree, acc, branch = [], build) =>
Object.entries(tree).reduce(
(a, [key, val]) =>
typeof val !== 'object'
? build(a, branch, key, val)
: flatten(val, a, branch.concat(key), build),
acc
);
console.log(
flatten(source, [], [], (acc, branch, key, val) => [
...acc,
branch.concat(key, val)
])
);
产出
[
[ 'a', 'b', 'c', 'c' ],
[ 'b', 'd', 'x', 'sdfdsgsf' ],
[ 'b', 'c', 'i', 'sdf' ],
[
'b', 'c',
'f', 'one',
'two', 'three',
'deep'
]
]
我需要将分支节点连接成一个字符串,例如
{
'a.b.c.d': 'string',
'x.y.z': 'foo'
}
所以我用了
flatten(source, {}, [], (acc, branch, key, val) => ({
...acc,
[branch.concat(key).join('.')]: val
}))