2016-06-21 8 views
2

Есть ли более краткий способ функционального добавления элемента в массив, являющийся свойством объекта?Краткий путь к неизменному добавлению объекта к массиву, который является свойством объекта и возвращает новый объект.

императив:

secitems.sections.push("Test") 
return secitems 

Функциональное:

const R = require("ramada") 
return Object.assign({}, secitems, { 
       sections: R.append(
        "Test", 
        secitems.sections 
       ) 
      }) 

Моя функциональная версия кажется слишком длинным и сложным по сравнению с императивной версии. Есть ли более сжатый способ написать его?

ответ

3

Update (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']} 

И если ваша структура данных должны были изменить, только код, который нужно будет изменить бы определение Lens себя:

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.

2
const R = require('ramda') 
return R.mergeWith(R.concat, secitems, { sections: ["Test"] })