Вместо того, чтобы указывать локаль во всех разборах, я предпочитаю устанавливать широко распространенный язык приложения, хотя, если строковые форматы не соответствуют друг другу, это может не сработать.
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-PT");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("pt-PT");
Определение это в начале вашего заявления сделает все двойные парсы ожидающими запятой как десятичным разделителем. Вы можете установить соответствующий языковой стандарт, чтобы разделитель десятичных и тысяч символов соответствовал строкам, которые вы обрабатываете.
Объективы - это, вероятно, ваш лучший выбор для этого. У 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
, так и вложенный объект с вашим внутренним идентификатором, вы можете написать более сложную линзу для этого, но он будет гораздо более тяжелым.
Небольшое примечание: «критерии» уже во множественном числе, поэтому «критерии» нечетны. Единственное число является «критерием».