У меня есть коллекция, которой Id нравится захватывать некоторые значения, и объединить их вместе, чтобы сформировать новое значение. До сих пор я смотрел на R.evolve
, но не повезло (потому что medias
также является коллекцией.
Это то, с чего я начинаю:
[{
"permalink": "http://example.com/1",
"medias": [{
"filename": "image_1.png",
}]
}, {
"permalink": "http://example.com/3",
"medias": [{
"filename": "image_3.png",
}]
}]
И это то, на что Id хотел бы закончить:
[{
"permalink": "http://example.com/1",
"medias": [{
"filename": "image_1.png",
"image_url": "http://example.com/1/image_1.png"
}]
}, {
"permalink": "http://example.com/3",
"medias": [{
"filename": "image_3.png",
"image_url": "http://example.com/3/image_3.png"
}]
}]
По сути дела, это добавление каждого filename
с permalink
.
Это то, к чему я до сих пор шел, к сожалению, при запуске преобразования на medias
я не могу получить доступ к свойству permalink
.
const mapMedia = R.map(
// cant get access to the 'permalink' in here?
)
const transformations = {
medias: mapMedia
}
const transform = R.compose(
R.map(R.evolve(transformations)),
)(data)
Таким образом, проблема в том, что требуемые данные не входят в объем. На мой взгляд, самый простой способ исправить это - добавить область!
Во- первых, вам не нужно, что compose
сообщения вызова, так как вы только поставляя ему одну функцию. Поэтому мы можем заменить
const transform = R.compose(
R.map(R.evolve(transformations)),
)(data)
с просто
const transform = R.map(R.evolve(transformations)),
(Я также удалил вызов с помощью (data)
, так как я пытаюсь создать это как функцию многократного использования. Затем мы будем вызывать его позже с помощью transform(data)
.
Теперь нам нужно добавить контекст, чтобы transformations
имели объект в области видимости. Мы можем сделать это вот так:
const transform = R.map(image => R.evolve(transformations(image), image));
Конечно, это означает, что transformations
необходимо изменить, чтобы учесть это. Мы можем сделать это вот так:
const transformations = image => ({
medias: mapMedia(image.permalink)
})
... и это, в свою очередь, требует изменения mapMedia
. Я думал, что ему нужно знать только о постоянной ссылке, а не обо всем изображении, поэтому мы можем передать только то, что указано выше. И mapMedia
теперь будет выглядеть так:
const mapMedia = permalink => R.map(
medium => // do something with 'medium' and 'permalink'
);
Существует много способов сделать этот последний шаг. Один из них, справедливо согласованный с вашим использованием evolve
, будет таким:
const mapMedia = permalink => R.map(
medium => assoc('image_url', permalink + '/' + medium.filename, medium)
);
Еще одной альтернативой, как evolve
и assoc
является исследование различных lens
-related функции в Ramda, такие как lensProp
, over
и set
.
Теперь, если эти вспомогательные функции используются только для этой цели, вы можете не захотеть, чтобы они загромождали вещи, и вы могли бы выбрать их в своей основной функции. Если вам понравилось, вы можете объединить все это в
const addUrls = map(
image => evolve({
medias: map(medium => assoc('image_url', image.permalink + '/' + medium.filename, medium)),
}, image)
);
Вы можете увидеть подход к R.map( medium => assoc('image_url', permalink + '/' + medium.filename, medium) ); const transformations = image => ({ medias: mapMedia(image.permalink) }) const transform = R.map(image => R.evolve(transformations(image), image)); transform(coll) rel="nofollow noreferrer">отдельным функциям или evolve({ medias: map(medium => assoc('image_url', image.permalink + '/' + medium.filename, medium)), }, image) ); addUrls(coll); rel="nofollow noreferrer">комбинированный в Ramda REPL. Для хорошей меры также есть over( lensProp('medias'), map(medium => set(lensProp('image_url'), image.permalink + '/' + medium.filename, medium)), image ) ); addUrls(coll); rel="nofollow noreferrer">версия с использованием объективов.
(И в отдельном примечании слово "медиа" уже есть множественное число. Единственное значение - "средний". Нет никаких веских оснований для "медиа".)