Как выполнить вложенное обновление с использованием Ramda в заданной структуре объекта?

Вместо того, чтобы указывать локаль во всех разборах, я предпочитаю устанавливать широко распространенный язык приложения, хотя, если строковые форматы не соответствуют друг другу, это может не сработать.

CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-PT");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("pt-PT");

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

2
задан William Calderipe 23 February 2019 в 00:12
поделиться

1 ответ

Объективы - это, вероятно, ваш лучший выбор для этого. У Ramda есть общая функция lens и специальные функции для свойства объекта ( lensProp ), для индекса массива ( lensIndex ), и для более глубокого пути ( lensPath ), но он не включает в себя один, чтобы найти совпадающее значение в массиве по id. Тем не менее, сделать свое дело несложно.

Объектив создается путем передачи двух функций в lens: метод получения, который принимает объект и возвращает соответствующее значение, и метод установки, который принимает новое значение и объект и возвращает обновленную версию объекта. ]

Здесь мы пишем lensMatch, который находит или устанавливает значение в массиве, где заданное имя свойства соответствует предоставленному значению. И lensId просто передает 'id' в lensMatch, чтобы вернуть функцию, которая примет значение id и вернет линзу.

Используя любой объектив, мы имеем функции view , set и over , которые, соответственно, получают, устанавливают и обновите значение.

Мы могли бы использовать idLens так:

const data = [{id: 'a'}, {id: 'b'}, {id: 'c'}]

view (idLens ('b'), data) 
  //=> {id: 'b'}
set  (idLens ('b'), 'foo', data) 
  //=> [ {id: 'a'}, 'foo', {id: 'c'} ]
over (idLens ('b'), merge ({name: 'foo'}), data)
  //=> [ {id: 'a'}, {id: 'b', name: 'foo}, {id: 'c'} ]

Итак, для вашей задачи мы могли бы написать что-то вроде этого:

const lensMatch = (propName) => (key) => lens
  ( find(propEq(propName, key))
    , (val, arr, idx = findIndex (propEq (propName, key), arr)) =>
         update(idx > -1 ? idx : length(arr), val, arr)
    )

const lensId = lensMatch('id')

const updateCriteria = (featureId, criteriaId, data, application) => over 
  ( compose 
      ( lensProp ('features')
      , lensId (featureId) 
      , lensProp ('criterias') 
      , lensId (criteriaId)
      )
    , merge (data)
    , application
    )

const application = {id: 'a1', features: [{id: 'f1', criterias: [{ id: 'c1' }]}, {id: 'f2', criterias: [{ id: 'c2' }, { id: 'c3' }]}]}

const newApp = updateCriteria ('f2', 'c2', {name: 'foo'}, application)

console.log(newApp)
[112 ]

Но это предполагает, что вы знаете featureId. Если вам нужно найти как featureId, так и вложенный объект с вашим внутренним идентификатором, вы можете написать более сложную линзу для этого, но он будет гораздо более тяжелым.


Небольшое примечание: «критерии» уже во множественном числе, поэтому «критерии» нечетны. Единственное число является «критерием».

0
ответ дан Scott Sauyet 23 February 2019 в 00:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: