Ramda — это практичная функциональная библиотека для программистов на JavaScript. Он следует парадигме функционального программирования, а официальный документ находится здесь. Одним из недостатков Ramda является то, что его документация слишком абстрактна, а кривая обучения слишком крутая!

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

Первая статья этой серии посвящена объективу или семейству функций, связанных с объективом.

Сначала зададим простой вопрос, почему функция называется «линза»? Понимание того, почему это важно, позволяет легко вспомнить, какую функцию использовать в Ramda, не обращаясь лишний раз к документу и искать функцию-кандидата среди сотен из них.

Объектив делает его фокусом, полной остановкой.

С объективом вы видите не всю картинку, а ее части, но с гораздо большим количеством деталей. Это полностью описывает, что такое объектив.

По аналогии с этим, если у вас очень большой объем данных, но вас интересует не весь набор данных, а его часть, и вы хотите манипулировать им, читать, записывать, удалять…. играть в.

С этим пониманием вы никогда не забудете, что такое объектив!

Пример 1: Используйте объектив для доступа/чтения данных:

const input = ['a', 'b', 'c']
const o1 = view(lensIndex(0), input);            //=> 'a'

Здесь lensIndex(0) говорит нам, что мы используем линзу для фокусировки на первом элементе, то есть на нем. Но подождите, мы знаем, что линза позволяет вам просматривать объект, но линза сама по себе не является объектом! Вот почему у нас есть родственное представление функции, которое возвращает сам элемент.

Эммм, я могу легко сделать то же самое, что и ниже, зачем беспокоиться?

const input = ['a', 'b', 'c']
const o1 = input[0]                              //=> 'a'

Совершенно верно! Но рассмотрим следующий пример 2:

const input = {
  id: 'a1',
  features: [
    {
      id: 'f1',
      children: [
        { id: 'c1' }
      ]
    },
    {
      id: 'f2',
      children: [
        { id: 'c2' },
        { id: 'c3' }
      ]
    }
  ]
};

Как вы получаете/сосредотачиваетесь на «c2» в этом? Нет тривиальных решений. Вот где в игру вступает LensPath:

const o1= view(lensPath(['features', 1, 'children', 0, 'id']), input) //c2

Вау! Это действительно мощно! Естественно это читается так:

const o1 = input ['features'][1][ 'children'][0].'id';

Точно так же мы можем также установить значение по этому пути в примере 3:

const output = set(lensPath(['features', 1, 'children', 0, 'id']), 'x100', input)

и теперь вывод:

{
    features: [
        {
            children: [
                {
                    id: "c1"
                }
            ],
            id: "f1"
        },
        {
            children: [
                {
                    id: "x100"   // <---- updated
                },
                {
                    id: "c3"
                }
            ],
            id: "f2"
        }
    ],
    id: "a1"
}

Если ваш путь к интересующему месту очень прост, вы также можете использовать LensProp для замены LensPath:

const o2= view(lensProp('features'), input) ;

а теперь О2

[
    {
        id: "f1"
        children: [
            {
                id: "c1"
            }
        ],
},
    {
        id: "f2"
        children: [
            {
                id: "c2"
            },
            {
                id: "c3"
            }
        ],
}
]

Вот и все.

Напомним, что вы можете использовать lensIndex, lensProp и lensPath, чтобы найти интересующие данные, это аналогично использованию линзы для фокусировки на определенных поля. Затем вы можете использовать view, set для чтения/записи значений.

Удачного кодирования.