Объединение полей объекта для создания нового поля с Рамдой

1

У меня есть коллекция, которой 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)
Теги:
ramda.js

1 ответ

2
Лучший ответ

Таким образом, проблема в том, что требуемые данные не входят в объем. На мой взгляд, самый простой способ исправить это - добавить область!

Во- первых, вам не нужно, что 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">версия с использованием объективов.


(И в отдельном примечании слово "медиа" уже есть множественное число. Единственное значение - "средний". Нет никаких веских оснований для "медиа".)

  • 0
    Большое спасибо за этот тщательный и отличный ответ. Это одна из причин, по которой мне так нравится использовать Ramda!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню