Обработка данных, которые могут быть массивом или одним значением, без условий

#javascript

#javascript

Вопрос:

У меня есть переменная data , которая может быть либо одним значением (скажем, это может быть объект, строка или число), либо массивом. Я хочу выполнить функцию для каждого элемента массива или для одного значения. В настоящее время у меня есть:

 let resu<
if (Array.isArray(data)) {
   result = data.map(d => f(d))
} else {
   result = f(data);
}
  

Я мог бы использовать троичный для того же эффекта, но я бы хотел удалить условный. Есть ли идиоматический способ сделать это?

Комментарии:

1. троичный — это условный. Не ясно, что вы пытаетесь сделать. result = Array.isArray(data) ? data.map(f) : f(data); должен дать тот же результат, что и у вас. Для меня это звучит как запах кода. Я бы ожидал, что результат всегда будет одного и того же типа, но возможно разрешить один элемент или несколько элементов. В этом случае это может сделать что-то вроде result = (Array.isArray(data) ? data : [data]).map(f);

2. Правильно — я бы хотел сделать это без троичного. Возможно ли это?

3. Если не считать обеспечения того, чтобы данные были массивом, я не понимаю, как это было бы возможно

4. Я так не думаю, потому что это не стандартный случай — почему вы не можете просто сделать входные данные согласованными и всегда возвращать массив, даже если есть только один элемент?

5. Существует простой способ преобразовать все в массив, используя JSON.stringify , а затем проверить массив внутри вашего map , но вы бы сильно усложнили ситуацию.

Ответ №1:

Вы можете добавить дополнительное измерение и использовать .flat() , чтобы избавиться от него

 [5].flat() // [5]
[[5]].flat() // [5]
  

таким образом, вы можете написать:

 [data].flat().map(f);
  

но это не имеет смысла и просто тратит время на вычисления; условное условие должно быть здесь быстрее.

Попробуйте просто сделать свой ввод согласованным и всегда передавать массив в это место (даже с одним элементом).

Ответ №2:

Вы можете использовать «эзотерический вид» function , который я вызываю fmap в этом примере (хотя название на самом деле неверно):

 function fmap (f, x) {
  return (function (g) {
    return g(f);
  })((x amp;amp; x.map amp;amp; x.map.bind(x)) || function (h) { return h(x); });
}

const upper = x => x.toUpperCase();

console.log('fmap over array:', fmap(upper, ['a', 'b', 'c']));
console.log('fmap over string:', fmap(upper, 'a'));  

WTF??

fmap принимает функцию и значение ( f и x ). Он вызывает IIFE, чтобы определить, реализует ли значение x map метод. Если это так, он привязывает этот map метод к значению. Если значение не реализует map метод, оно создает анонимную функцию, которая принимает другую функцию и вызывает эту другую функцию со значением x .

Наконец, он возвращает результат вычисления.

Дальнейшие размышления

Честно говоря, мое личное мнение — использовать условное! Это намного проще понять и рассуждать. В любом случае, это выполнимо без условного оператора или троичного оператора.