RamdaJS 转换对象并使用另一个列表进行查找
RamdaJS transform object and do lookup with another lists
从
继续
let children = [
{ "name": "Bob", "age": 8, "father": "Mike" },
{ "name": "David", "age": 10, "father": "Mike" },
{ "name": "Amy", "age": 2, "father": "Mike" },
{ "name": "Jeff", "age": 11, "father": "Jack" }
]
let schoolList = [
{ "name": "Bob", "class": "8-A", "school": "School 1" },
{ "name": "David", "class": "10-B", "school": "School 1" },
{ "name": "Amy", "class": "2-A", "school": "School 1" },
{ "name": "Jeff", "class": "11-C", "school": "School 1" }
]
到目前为止我做了什么。
R.pipe(
R.groupBy(R.prop('father')),
R.map(R.applySpec({
father: R.pipe(R.head, R.prop('father')),
count: R.length,
kids: R.map(R.dissoc('father')),
class: R.map(R.prop('class'))R.find(R.propEq('name',R.pipe(R.head, R.prop('name'))), schoolList)
})),
R.values()
)(children)
预期输出是 class 属性 附加到嵌套的 kids 数组。
{
"father": "Jack",
"count" : 1,
"kids": [
{ "name": "Jeff", "age": 11, "class" : "11-C" }
]
}
使用 R.indexBy
将 schoolList
转换为 object 的字典。通过使用翻转道具从查找中获取来创建 pickFromLookupByName
。使用pick
提取你想要的道具
要将 class
添加到孩子 object 使用 R.converge
将孩子 object 与 R.identity
相加,并使用 pickClass
获得包含 class
的 object,并将两者与 R.mergeRight
.
合并
const { pipe, groupBy, prop, applySpec, head, length, map, dissoc, values, indexBy, converge, mergeRight, flip, pick, identity } = R
const schoolList = [{"name":"Bob","class":"8-A","school":"School 1"},{"name":"David","class":"10-B","school":"School 1"},{"name":"Amy","class":"2-A","school":"School 1"},{"name":"Jeff","class":"11-C","school":"School 1"}]
const schoolLookup = indexBy(prop('name'), schoolList);
const pickFromLookupByName = (propList) => pipe(
flip(prop)(schoolLookup),
pick(propList),
)
const pickClass = pickFromLookupByName(['class']) // convenience method to get an object containing the class
const fn = pipe(
groupBy(prop('father')),
map(applySpec({
father: pipe(head, prop('father')),
count: length,
kids: map(pipe(
dissoc('father'),
converge(mergeRight, [identity, pipe(prop('name'), pickClass)])
))
})),
values
)
const children = [{"name":"Bob","age":8,"father":"Mike"},{"name":"David","age":10,"father":"Mike"},{"name":"Amy","age":2,"father":"Mike"},{"name":"Jeff","age":11,"father":"Jack"}]
const result = fn(children)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
如果实际的schoolList
很长,我会使用OriDrori的答案。但如果它相当短,那么这可能会更干净一些,即使效率较低:
const expandChild = schoolList => child => ({
...child,
class: defaultTo(
{class: 'unknown'},
find(propEq('name', child.name), schoolList)
).class
})
const groupChildren = schoolList => pipe(
groupBy(prop('father')),
map(applySpec({
father: pipe(head, prop('father')),
count: length,
kids: map(pipe(dissoc('father'), expandChild(schoolList)))
})),
values,
)
let children = [{ name: "Bob", age: 8, father: "Mike" }, { name: "David", age: 10, father: "Mike" }, { name: "Amy", age: 2, father: "Mike" }, { name: "Jeff", age: 11, father: "Jack" }, { name: "Sue", age: 9, father: "Jack" }]
let schoolList = [{ name: "Bob", class: "8-A", school: "School 1" }, { name: "David", class: "10-B", school: "School 1" }, { name: "Amy", class: "2-A", school: "School 1" }, { name: "Jeff", class: "11-C", school: "School 1" }]
console.log (groupChildren (schoolList) (children))
<script src="https://bundle.run/ramda@0.26.1"></script><script>
const {defaultTo, find, propEq, pipe, groupBy, map, applySpec, head, prop, length, dissoc, values} = ramda
</script>
注意 school
的默认值,以防 child 的名字不在 schoolList
中。
从
let children = [
{ "name": "Bob", "age": 8, "father": "Mike" },
{ "name": "David", "age": 10, "father": "Mike" },
{ "name": "Amy", "age": 2, "father": "Mike" },
{ "name": "Jeff", "age": 11, "father": "Jack" }
]
let schoolList = [
{ "name": "Bob", "class": "8-A", "school": "School 1" },
{ "name": "David", "class": "10-B", "school": "School 1" },
{ "name": "Amy", "class": "2-A", "school": "School 1" },
{ "name": "Jeff", "class": "11-C", "school": "School 1" }
]
到目前为止我做了什么。
R.pipe(
R.groupBy(R.prop('father')),
R.map(R.applySpec({
father: R.pipe(R.head, R.prop('father')),
count: R.length,
kids: R.map(R.dissoc('father')),
class: R.map(R.prop('class'))R.find(R.propEq('name',R.pipe(R.head, R.prop('name'))), schoolList)
})),
R.values()
)(children)
预期输出是 class 属性 附加到嵌套的 kids 数组。
{
"father": "Jack",
"count" : 1,
"kids": [
{ "name": "Jeff", "age": 11, "class" : "11-C" }
]
}
使用 R.indexBy
将 schoolList
转换为 object 的字典。通过使用翻转道具从查找中获取来创建 pickFromLookupByName
。使用pick
提取你想要的道具
要将 class
添加到孩子 object 使用 R.converge
将孩子 object 与 R.identity
相加,并使用 pickClass
获得包含 class
的 object,并将两者与 R.mergeRight
.
const { pipe, groupBy, prop, applySpec, head, length, map, dissoc, values, indexBy, converge, mergeRight, flip, pick, identity } = R
const schoolList = [{"name":"Bob","class":"8-A","school":"School 1"},{"name":"David","class":"10-B","school":"School 1"},{"name":"Amy","class":"2-A","school":"School 1"},{"name":"Jeff","class":"11-C","school":"School 1"}]
const schoolLookup = indexBy(prop('name'), schoolList);
const pickFromLookupByName = (propList) => pipe(
flip(prop)(schoolLookup),
pick(propList),
)
const pickClass = pickFromLookupByName(['class']) // convenience method to get an object containing the class
const fn = pipe(
groupBy(prop('father')),
map(applySpec({
father: pipe(head, prop('father')),
count: length,
kids: map(pipe(
dissoc('father'),
converge(mergeRight, [identity, pipe(prop('name'), pickClass)])
))
})),
values
)
const children = [{"name":"Bob","age":8,"father":"Mike"},{"name":"David","age":10,"father":"Mike"},{"name":"Amy","age":2,"father":"Mike"},{"name":"Jeff","age":11,"father":"Jack"}]
const result = fn(children)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
如果实际的schoolList
很长,我会使用OriDrori的答案。但如果它相当短,那么这可能会更干净一些,即使效率较低:
const expandChild = schoolList => child => ({
...child,
class: defaultTo(
{class: 'unknown'},
find(propEq('name', child.name), schoolList)
).class
})
const groupChildren = schoolList => pipe(
groupBy(prop('father')),
map(applySpec({
father: pipe(head, prop('father')),
count: length,
kids: map(pipe(dissoc('father'), expandChild(schoolList)))
})),
values,
)
let children = [{ name: "Bob", age: 8, father: "Mike" }, { name: "David", age: 10, father: "Mike" }, { name: "Amy", age: 2, father: "Mike" }, { name: "Jeff", age: 11, father: "Jack" }, { name: "Sue", age: 9, father: "Jack" }]
let schoolList = [{ name: "Bob", class: "8-A", school: "School 1" }, { name: "David", class: "10-B", school: "School 1" }, { name: "Amy", class: "2-A", school: "School 1" }, { name: "Jeff", class: "11-C", school: "School 1" }]
console.log (groupChildren (schoolList) (children))
<script src="https://bundle.run/ramda@0.26.1"></script><script>
const {defaultTo, find, propEq, pipe, groupBy, map, applySpec, head, prop, length, dissoc, values} = ramda
</script>
注意 school
的默认值,以防 child 的名字不在 schoolList
中。