Ответ 1
Это должно быть возможно, создав объектив, который соответствует объекту по идентификатору, который затем может быть скомпонован с другими объективами, чтобы развернуться к полю изображения.
Для начала мы можем создать объектив, который будет фокусироваться на элементе массива, который соответствует некоторому предикату (обратите внимание: это будет только действительный объектив, если он будет соответствовать как минимум одному элементу списка)
//:: (a -> Boolean) -> Lens [a] a
const lensMatching = pred => (toF => entities => {
const index = R.findIndex(pred, entities);
return R.map(entity => R.update(index, entity, entities),
toF(entities[index]));
});
Обратите внимание, что мы вручную создаем объектив здесь, а не используя R.lens
, чтобы сохранить дублирование поиска индекса элемента, соответствующего предикату.
Как только мы получим эту функцию, мы можем построить объектив, соответствующий данному ID.
//:: String -> Lens [{ id: String }] { id: String }
const lensById = R.compose(lensMatching, R.propEq('id'))
И тогда мы сможем собрать все линзы вместе, чтобы направить поле изображения
const imageLens = R.compose(
R.lensProp('groups'),
lensById('/1/B'),
R.lensProp('apps'),
lensById('/1/B/i'),
R.lensPath(['container', 'docker', 'image'])
)
Что можно использовать для обновления объекта data
следующим образом:
set(imageLens, 'NAME:VERSION2', data)
Затем вы можете сделать это еще дальше, если хотите и объявите объектив, который фокусируется на версии строки изображения.
const vLens = R.lens(
R.compose(R.nth(1), R.split(':')),
(version, str) => R.replace(/:.*/, ':' + version, str)
)
set(vLens, 'v2', 'NAME:v1') // 'NAME:v2'
Затем он может быть добавлен в состав imageLens
для таргетинга версии внутри всего объекта.
const verLens = compose(imageLens, vLens);
set(verLens, 'VERSION2', data);