将对象不可变地添加到数组的简洁方法,该数组是对象的 属性 和新对象的 return
Concise way to immutably add object to an array that is a property of an object and return the new object
是否有更简洁的方法来在功能上将项目添加到作为对象的 属性 的数组?
命令式:
secitems.sections.push("Test")
return secitems
功能性:
const R = require("ramada")
return Object.assign({}, secitems, {
sections: R.append(
"Test",
secitems.sections
)
})
与命令式版本相比,我的函数式版本似乎太长太复杂了。有没有更简洁的写法?
const R = require('ramda')
return R.mergeWith(R.concat, secitems, { sections: ["Test"] })
更新 (TL;DR)
我会这样做:
const seclens = lensProp('sections');
over(seclens, append('Test'), secitems);
//=> {id: 123, sections: ['Foo', 'Bar, 'Test']}
有多种方法可以更简洁地执行此操作。其中一些还解决了您的原始代码无法处理的问题:
// This works fine
const secitems = {id: 123, sections: ['Foo', 'Bar']};
secitems.sections.push("Test")
secitems; //=> {id: 123, sections: ['Foo', 'Bar', 'Test']}
// But this is a problem
const secitems = {id: 123};
secitems.sections.push("Test")
secitems; //=> throws "secitems.sections is undefined"
我使用 Ramda 的首选方法是使用镜头:
const secitems = {id: 123, sections: ['Foo', 'Bar']};
over(lensProp('sections'), append('Test'), secitems);
//=> {id: 123, sections: ['Foo', 'Bar, 'Test']}
这样做的好处是镜头本身在多种情况下都很有用:
const seclens = lensProp('sections');
const getSections = view(seclens);
getSections(secitems); //=> ['Foo', 'Bar']
const setSections = set(seclens);
setSections(['Baz, Qux'], secitems)
//=> {id: 123, sections: ['Baz', 'Qux']}
setSections(['Baz', 'Qux'], {id: 456})
//=> {id: 456, sections: ['Baz', 'Qux']}
如果您的数据结构要更改,唯一需要更改的代码就是镜头定义本身:
const obj = {id: 123, secitems: {sections: ['Foo', 'Bar']}};
over(lensPath(['secitems', 'sections']), append('Test'), obj);
//=> {id: 123, secitems: {sections: ['Foo', 'Bar, 'Test']}}
或
const seclens = lensPath(['secitems', 'sections']);
const getSections = view(seclens);
getSections(obj); //=> ['Foo', 'Bar']
const setSections = set(seclens);
setSections(['Baz, Qux'], obj)
//=> {id: 123, secitems: {sections: ['Baz', 'Qux']}}
setSections(['Baz', 'Qux'], {id: 456})
//=> {id: 456, secitems: {sections: ['Baz', 'Qux']}}
Ramda's lens
documentation中有更多信息。
是否有更简洁的方法来在功能上将项目添加到作为对象的 属性 的数组?
命令式:
secitems.sections.push("Test")
return secitems
功能性:
const R = require("ramada")
return Object.assign({}, secitems, {
sections: R.append(
"Test",
secitems.sections
)
})
与命令式版本相比,我的函数式版本似乎太长太复杂了。有没有更简洁的写法?
const R = require('ramda')
return R.mergeWith(R.concat, secitems, { sections: ["Test"] })
更新 (TL;DR)
我会这样做:
const seclens = lensProp('sections');
over(seclens, append('Test'), secitems);
//=> {id: 123, sections: ['Foo', 'Bar, 'Test']}
有多种方法可以更简洁地执行此操作。其中一些还解决了您的原始代码无法处理的问题:
// This works fine
const secitems = {id: 123, sections: ['Foo', 'Bar']};
secitems.sections.push("Test")
secitems; //=> {id: 123, sections: ['Foo', 'Bar', 'Test']}
// But this is a problem
const secitems = {id: 123};
secitems.sections.push("Test")
secitems; //=> throws "secitems.sections is undefined"
我使用 Ramda 的首选方法是使用镜头:
const secitems = {id: 123, sections: ['Foo', 'Bar']};
over(lensProp('sections'), append('Test'), secitems);
//=> {id: 123, sections: ['Foo', 'Bar, 'Test']}
这样做的好处是镜头本身在多种情况下都很有用:
const seclens = lensProp('sections');
const getSections = view(seclens);
getSections(secitems); //=> ['Foo', 'Bar']
const setSections = set(seclens);
setSections(['Baz, Qux'], secitems)
//=> {id: 123, sections: ['Baz', 'Qux']}
setSections(['Baz', 'Qux'], {id: 456})
//=> {id: 456, sections: ['Baz', 'Qux']}
如果您的数据结构要更改,唯一需要更改的代码就是镜头定义本身:
const obj = {id: 123, secitems: {sections: ['Foo', 'Bar']}};
over(lensPath(['secitems', 'sections']), append('Test'), obj);
//=> {id: 123, secitems: {sections: ['Foo', 'Bar, 'Test']}}
或
const seclens = lensPath(['secitems', 'sections']);
const getSections = view(seclens);
getSections(obj); //=> ['Foo', 'Bar']
const setSections = set(seclens);
setSections(['Baz, Qux'], obj)
//=> {id: 123, secitems: {sections: ['Baz', 'Qux']}}
setSections(['Baz', 'Qux'], {id: 456})
//=> {id: 456, secitems: {sections: ['Baz', 'Qux']}}
Ramda's lens
documentation中有更多信息。