Усовершенствованное преобразование массива Ramda - PullRequest
0 голосов
/ 09 ноября 2018

TLTR: Посмотрите на фрагмент JavaScript.

У меня есть массив предметов.

Я хочу отобразить элементы и изменить их структуру.

Мне нужно сохранить некоторые свойства, а также мне нужно установить новое свойство. Однако новое значение свойства будет основываться на элементе, который я сейчас отображаю.

// change title to whatever shape you desire
const customTitleTransformation = title => title

const arrayOfItems = [
  {
    id: 'some id 1',
    isSelected: true,
    title: 'some title 1',
    text: 'some text',
    description: 'some description'
  },
  {
    id: 'some id 2',
    isSelected: false,
    title: 'some title 2',
    text: 'some text',
    description: 'some description'
  },
]

// I need array of items like:
// {
//   id,
//   isSelected,
//   cells: [
//     customTitleTransformation(title),
//     text
//   ]
// }

// REGULAR JAVASCRIPT WAY  
const normalizedItems = arrayOfItems.map(item => ({
  id: item.id,
  isSelected: item.isSelected,
  cells: [
    customTitleTransformation(item.title),
    item.text,
  ]
}))

console.log('first result ', normalizedItems)

// USING RAMDA  

const normalizedItemsRamda = R.map(
  R.compose(
    R.pick(['id', 'isSelected', 'cells']),
    R.set(R.lensProp('cells'), ['how do I set the array?'])
  )
)(arrayOfItems)

console.log('ramda result ', normalizedItemsRamda)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Я думаю, что это может иметь место для applySpec.

Функция mapObject определяет форму нового объекта. Затем это преобразование применяется к arrayOfItems.

Если вы чувствуете, что это более читабельно, конечно, оставьте на ваше усмотрение:

// change title to whatever shape you desire
const customTitleTransformation = title => title

const arrayOfItems = [{
    id: 'some id 1',
    isSelected: true,
    title: 'some title 1',
    text: 'some text',
    description: 'some description'
  },
  {
    id: 'some id 2',
    isSelected: false,
    title: 'some title 2',
    text: 'some text',
    description: 'some description'
  },
]

const mapObject = R.applySpec({
  id: R.prop('id'),
  isSelected: R.prop('isSelected'),
  cells: R.juxt([
    R.o(customTitleTransformation, R.prop('title')),
    R.prop('text')
  ])
});

const normalizedItemsRamda = R.map(mapObject, arrayOfItems)

console.log('ramda result ', normalizedItemsRamda)
console.log('\n\nOriginal Items Unchanged:')
console.log(arrayOfItems);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
0 голосов
/ 09 ноября 2018

Я не эксперт по Рамде или ФП, как ни крути, но кажется, что проще всего было бы передать нормальную функцию в R.compose, которая добавляет свойство ячейки к каждому объекту до pick свойства, которые вы хотите.

Дайте мне знать, если это работает для вас, или это анти-паттерн, и вы строго ищете встроенные модули Рамды.

// change title to whatever shape you desire
const customTitleTransformation = title => title

const arrayOfItems = [
  {
    id: 'some id 1',
    isSelected: true,
    title: 'some title 1',
    text: 'some text',
    description: 'some description'
  },
  {
    id: 'some id 2',
    isSelected: false,
    title: 'some title 2',
    text: 'some text',
    description: 'some description'
  },
]

// USING RAMDA  

const normalizedItemsRamda = R.map(
  R.compose(
    R.pick(['id', 'isSelected', 'cells']),
    // shallow copy, add cells property, return new updated object
    item => R.assoc('cells', [customTitleTransformation(item.title), item.text], item)
  )
)(arrayOfItems)

console.log('ramda result ', normalizedItemsRamda)
console.log('\n\nOriginal Items Unchanged:')
console.log(arrayOfItems);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
...