Как условно изменить значение с помощью when() в JavaScript

kak uslovno izmenit znachenie s pomoshhyu when v javascript

30 Seconds of Code – это отличная коллекция фрагментов JavaScript, которую можно усвоить за ≤ 30 секунд. Каждый, кто хочет освоить JavaScript, должен пройти через все.

Вдохновленный Ramda, я внес вклад when() к официальному репо GitHub 30secondsofcode. Это одна из моих любимых функций.

when() принимает 3 параметра:

  1. pred: предикатная функция (должна возвращать true или false)
  2. whenTrue: функция для запуска if pred возвращается true.
  3. Значение: x.

Вот самая простая реализация:

when = (pred, whenTrue, x) => {
  if (pred(x)) {
    return whenTrue(x);
  } else {
    return x;
  }
};

Который можно сократить до:

when = (pred, whenTrue, x) => (pred(x) ? whenTrue(x) : x);

Скажем, мы хотим утроить четные числа

when((x) => x % 2 === 0, (x) => x * 3, 2);
// 6

Мы получили 6 поскольку 2 является четным числом. А если мы пройдем 11?

when((x) => x % 2 === 0, (x) => x * 3, 11);
// 11

Шаг дальше

when требуются все 3 параметра одновременно. Что, если бы мы могли предоставить только первые 2 и предоставить x позже?

when = (pred, whenTrue) => (x) => (pred(x) ? whenTrue(x) : x);

Эту версию я отправил на 30secondsofcode.org. Теперь наш код стал более гибким.

tripleEvenNums = when((x) => x % 2 === 0, (x) => x * 3);

tripleEvenNums(20); // 60
tripleEvenNums(21); // 21
tripleEvenNums(22); // 66

Даже дальше

Мы можем пройти x позже потому что when(pred, whenTrue) возвращает ожидающую функцию x. А если мы карри when()?

Если вы новичок в карри, посмотрите мою статью об этом.

Каррированной функции не требуются все параметры одновременно. Вы можете предоставить часть и получить функцию, которая берет на себя сдачу, создавая мощные шаблоны.

Глупый пример

Представьте, что у нас есть два списка людей, оба содержат парня с именем Bobo.

Bobo хочет псевдоним для каждого списка.

  • Если найдем Bobo в списке 1 изменить его имя на B Money.
  • Если найдем Bobo в списке 2 изменить его имя на Bo-bob.

Карри when позволяет нам легко написать функцию для каждой задачи.

Если вы следите, вот a curry функция из 30secondsofcode.org.

curry = (fn, arity = fn.length, ...args) =>
  arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);

Для поиска нам понадобится предикат Bobo.

isBobo = (person) => person.name === 'Bobo';

Чтобы сохранить наши функции чистыми, нам понадобится способ неизменно изменить имя человека.

changeName = (newName, obj) => ({
  ...obj,
  name: newName
});

Давайте также заправим его, чтобы мы могли просто поставлять newName.

changeName = curry((newName, obj) => ({
  ...obj,
  name: newName
}));

Вот наши списки.

list1 = [
  {
    name: 'Bobo',
    id: 1,
    iq: 9001
  },
  {
    name: 'Jaime',
    id: 2,
    iq: 9000
  },
  {
    name: 'Derek',
    id: 3,
    iq: 8999
  }
];

list2 = [
  {
    name: 'Sam',
    id: 1,
    iq: 600
  },
  {
    name: 'Bobo',
    id: 2,
    iq: 9001
  },
  {
    name: 'Peter',
    id: 3,
    iq: 8
  }
];

Давайте нанесем карту list1.

doIfBobo = when(isBobo);
renameToBMoney = changeName('B Money');

list1.map(doIfBobo(renameToBMoney));

Наш результат:

[
  {
    name: 'B Money',
    id: 1,
    iq: 9001
  },
  {
    name: 'Jaime',
    id: 2,
    iq: 9000
  },
  {
    name: 'Derek',
    id: 3,
    iq: 8999
  }
];

Потому что whenмы только изменились Bobo и проигнорировал всех остальных!

Теперь посмотрите карту list2.

renameToBoBob = changeName('Bo-bob');

list2.map(doIfBobo(renameToBoBob));
Our result:

[{
  "name": "Sam",
  "id": 1,
  "iq": 600
},
 {
 "name": "Bo-bob",
   "id": 2,
   "iq": 9001**
 },
 {
   "name": "Peter",
   "id": 3,
   "iq": 8
 }
];

Выглядит мне хорошо! Мы дали Bobo его прозвища, не затрагивая других.

Если вы еще заинтересованы, просмотрите эти ссылки:

Добавить комментарий

Ваш адрес email не будет опубликован.