ramda 从基础对象重塑对象结构
ramda reshape object structure from base object
我确信在 api 请求后可以获取一个对象并修改它并过滤它以获得另一个形状以便于使用,但不幸的是我无法创建任何优雅的解决方案不要涉及对每个键使用 path
和 prop
,例如
const { prop, path } = R
const baseObject = {
id: 1,
name: 'object-one',
info: {
items: [
{ name: 'item-one', url: '/images/item-one.jpg' },
]
},
}
const newObj = {
id: prop('id', baseObject),
name: prop('name', baseObject),
// image is a new prop not found on the base object
image: path(['info', 'items', 0, 'url'], baseObject),
}
console.log(newObj)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>
任何人都可以告诉我是否有办法进行优雅的 pointfree 对象 reshaping。似乎应该有一些映射器函数可以将基础对象作为种子,但我似乎无法确定它。
我已经尝试过 evolve
但那并没有增加新的点,我已经尝试过 lens
但我可能遗漏了文档中的某些内容,因为我只能修改现有的键或像这样过滤prop
.
干杯,
edit. I was able to create a mapping function that will do the job, but is there a better way?
const { prop, path, toUpper, map, compose } = R
const baseObject = {
id: 1,
name: 'object-one',
info: {
items: [
{ name: 'item-one', url: '/images/item-one.jpg' },
]
},
}
// createObjectFromSpec :: { k: f(a) } -> a -> { k: b }
const createObjectFromSpec = spec => baseObj => R.map(f => f(baseObj), spec);
const createObjectTypeOne = createObjectFromSpec({
id: prop('id'),
name: prop('name'),
// image is a new prop not found on the base object
image: path(['info', 'items', 0, 'url']),
})
const createObjectTypeTwo = createObjectFromSpec({
id: prop('id'),
name: prop('name'),
// image is a new prop not found on the base object
itemName: path(['info', 'items', 0, 'name']),
})
console.log(
createObjectTypeOne(baseObject)
)
console.log(
createObjectTypeTwo(baseObject)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>
您示例中的 createObjectFromSpec
函数在 Ramda 中作为 applySpec
存在。
const fn = R.applySpec({
id: R.prop('id'),
name: R.prop('name'),
image: R.path(['info', 'items', 0, 'url'])
})
const result = fn({
id: 1,
name: 'object-one',
info: {
items: [
{ name: 'item-one', url: '/images/item-one.jpg' },
]
},
})
console.log(result)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
我确信在 api 请求后可以获取一个对象并修改它并过滤它以获得另一个形状以便于使用,但不幸的是我无法创建任何优雅的解决方案不要涉及对每个键使用 path
和 prop
,例如
const { prop, path } = R
const baseObject = {
id: 1,
name: 'object-one',
info: {
items: [
{ name: 'item-one', url: '/images/item-one.jpg' },
]
},
}
const newObj = {
id: prop('id', baseObject),
name: prop('name', baseObject),
// image is a new prop not found on the base object
image: path(['info', 'items', 0, 'url'], baseObject),
}
console.log(newObj)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>
任何人都可以告诉我是否有办法进行优雅的 pointfree 对象 reshaping。似乎应该有一些映射器函数可以将基础对象作为种子,但我似乎无法确定它。
我已经尝试过 evolve
但那并没有增加新的点,我已经尝试过 lens
但我可能遗漏了文档中的某些内容,因为我只能修改现有的键或像这样过滤prop
.
干杯,
edit. I was able to create a mapping function that will do the job, but is there a better way?
const { prop, path, toUpper, map, compose } = R
const baseObject = {
id: 1,
name: 'object-one',
info: {
items: [
{ name: 'item-one', url: '/images/item-one.jpg' },
]
},
}
// createObjectFromSpec :: { k: f(a) } -> a -> { k: b }
const createObjectFromSpec = spec => baseObj => R.map(f => f(baseObj), spec);
const createObjectTypeOne = createObjectFromSpec({
id: prop('id'),
name: prop('name'),
// image is a new prop not found on the base object
image: path(['info', 'items', 0, 'url']),
})
const createObjectTypeTwo = createObjectFromSpec({
id: prop('id'),
name: prop('name'),
// image is a new prop not found on the base object
itemName: path(['info', 'items', 0, 'name']),
})
console.log(
createObjectTypeOne(baseObject)
)
console.log(
createObjectTypeTwo(baseObject)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>
您示例中的 createObjectFromSpec
函数在 Ramda 中作为 applySpec
存在。
const fn = R.applySpec({
id: R.prop('id'),
name: R.prop('name'),
image: R.path(['info', 'items', 0, 'url'])
})
const result = fn({
id: 1,
name: 'object-one',
info: {
items: [
{ name: 'item-one', url: '/images/item-one.jpg' },
]
},
})
console.log(result)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>