Javascript 或 Ramda 按属性转换 JSON
Javascript or Ramda Transform JSON By Attributes
我在我的项目中使用 Ramda library。
是否可以转换以下 JSON 数组
来自
[
{
"id": 1,
"name": "test",
},
{
"id": 2,
"name": "test2"
}
];
到
[
{
"id": 1,
"id": 2,
},
{
"name": "test",
"name": "test2"
}
];
求助
对象不能有多个具有相同键的属性,所以
{ "id": 1, "id": 2 }
和 { "name": "test", "name": "test2" }
无效。我假设您需要一个 ID 数组和一个名称数组:
[[1, 2, 3], ['test', 'test2', 'test3']]
如果所有对象都具有相同的键顺序 - 即没有 { id: 1, name: 'test'}
和 { name: 'test2', id: 1 }
,并且您需要对象中的所有值,则可以将对象映射到它们的值,并且然后转置:
const { pipe, map, values, transpose } = R;
const fn = pipe(
map(values),
transpose,
);
const arr = [{"id":1,"name":"test"},{"id":2,"name":"test2"},{"id":3,"name":"test3"}];
const result = fn(arr);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
如果某些对象有不同的键插入顺序,你想改变结果数组的顺序,或者如果你需要一些键,你可以用R.props获取值,然后转置:
const { pipe, map, props, transpose } = R;
const fn = pipe(
map(props(['name', 'id'])), // example - name would be the 1st sub-array
transpose,
);
const arr = [{"id":1,"name":"test"},{"id":2,"name":"test2"},{"id":3,"name":"test3"}];
const result = fn(arr);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
如果您想要 Scott Sauyet 建议的结构:
{
id: [1, 2],
name: ['test1', 'test2']
}
我会用 R.chain 和 R.toPairs 将对象映射并展平到一对数组中,按每对中的第一个项目(原始键)对它们进行分组,然后映射每个组每对中的项目到最后一项(原始值)。
const { pipe, chain, toPairs, groupBy, head, map, last } = R
const fn = pipe(
chain(toPairs),
groupBy(head),
map(map(last)), // map(pipe(map(last), uniq)) if you want only unique items
)
const arr = [{"id":1,"name":"test"},{"id":2,"name":"test2"},{"id":3,"name":"test3"}];
console.log(fn(arr))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
正如 OriDrori 所指出的,您请求的输出不是有效的 JS。不过,关于它的一个有用的有效变体,我将做出稍微不同的猜测,即我们想要这样的输出:
{
id: [1, 2],
name: ['test1', 'test2']
}
这是在 vanilla JS 中实现这一点的一种简单方法:
const extract = (data) => {
const keys = [... new Set (data .flatMap (Object .keys))]
return Object .fromEntries (
keys.map (k => [k, data .map (o => o [k])])
)
}
const data = [{id: 1, name: "test"}, {id: 2, name: "test2"}]
console .log (
extract (data)
)
我们绝对可以使用 Ramda 函数来清理它。另一个版本可能如下所示:
const extract = (data) => fromPairs (
map (k => [k, map (o => o [k], data)]) (uniq (chain (keys) (data)))
)
const data = [{id: 1, name: "test"}, {id: 2, name: "test2"}]
console .log (extract (data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
<script> const {fromPairs, map, uniq, chain, keys} = R </script>
虽然我们可以完全不加分,但我发现这个版本的可读性要差得多:
const extract = compose (
fromPairs,
lift (map) (
unary (compose (ap (pair), flip (pluck))),
compose (uniq, chain (keys))
)
)
const data = [
{id: 1, name: "test"},
{id: 2, name: "test2"}
]
console .log (extract (data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
<script>
const {compose, fromPairs, lift, map, unary, ap, pair, flip, pluck, uniq, chain, keys} = R
</script>
我在我的项目中使用 Ramda library。
是否可以转换以下 JSON 数组
来自
[
{
"id": 1,
"name": "test",
},
{
"id": 2,
"name": "test2"
}
];
到
[
{
"id": 1,
"id": 2,
},
{
"name": "test",
"name": "test2"
}
];
求助
对象不能有多个具有相同键的属性,所以
{ "id": 1, "id": 2 }
和 { "name": "test", "name": "test2" }
无效。我假设您需要一个 ID 数组和一个名称数组:
[[1, 2, 3], ['test', 'test2', 'test3']]
如果所有对象都具有相同的键顺序 - 即没有 { id: 1, name: 'test'}
和 { name: 'test2', id: 1 }
,并且您需要对象中的所有值,则可以将对象映射到它们的值,并且然后转置:
const { pipe, map, values, transpose } = R;
const fn = pipe(
map(values),
transpose,
);
const arr = [{"id":1,"name":"test"},{"id":2,"name":"test2"},{"id":3,"name":"test3"}];
const result = fn(arr);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
如果某些对象有不同的键插入顺序,你想改变结果数组的顺序,或者如果你需要一些键,你可以用R.props获取值,然后转置:
const { pipe, map, props, transpose } = R;
const fn = pipe(
map(props(['name', 'id'])), // example - name would be the 1st sub-array
transpose,
);
const arr = [{"id":1,"name":"test"},{"id":2,"name":"test2"},{"id":3,"name":"test3"}];
const result = fn(arr);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
如果您想要 Scott Sauyet 建议的结构:
{
id: [1, 2],
name: ['test1', 'test2']
}
我会用 R.chain 和 R.toPairs 将对象映射并展平到一对数组中,按每对中的第一个项目(原始键)对它们进行分组,然后映射每个组每对中的项目到最后一项(原始值)。
const { pipe, chain, toPairs, groupBy, head, map, last } = R
const fn = pipe(
chain(toPairs),
groupBy(head),
map(map(last)), // map(pipe(map(last), uniq)) if you want only unique items
)
const arr = [{"id":1,"name":"test"},{"id":2,"name":"test2"},{"id":3,"name":"test3"}];
console.log(fn(arr))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
正如 OriDrori 所指出的,您请求的输出不是有效的 JS。不过,关于它的一个有用的有效变体,我将做出稍微不同的猜测,即我们想要这样的输出:
{
id: [1, 2],
name: ['test1', 'test2']
}
这是在 vanilla JS 中实现这一点的一种简单方法:
const extract = (data) => {
const keys = [... new Set (data .flatMap (Object .keys))]
return Object .fromEntries (
keys.map (k => [k, data .map (o => o [k])])
)
}
const data = [{id: 1, name: "test"}, {id: 2, name: "test2"}]
console .log (
extract (data)
)
我们绝对可以使用 Ramda 函数来清理它。另一个版本可能如下所示:
const extract = (data) => fromPairs (
map (k => [k, map (o => o [k], data)]) (uniq (chain (keys) (data)))
)
const data = [{id: 1, name: "test"}, {id: 2, name: "test2"}]
console .log (extract (data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
<script> const {fromPairs, map, uniq, chain, keys} = R </script>
虽然我们可以完全不加分,但我发现这个版本的可读性要差得多:
const extract = compose (
fromPairs,
lift (map) (
unary (compose (ap (pair), flip (pluck))),
compose (uniq, chain (keys))
)
)
const data = [
{id: 1, name: "test"},
{id: 2, name: "test2"}
]
console .log (extract (data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
<script>
const {compose, fromPairs, lift, map, unary, ap, pair, flip, pluck, uniq, chain, keys} = R
</script>