#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
.
Наконец, он возвращает результат вычисления.
Дальнейшие размышления
Честно говоря, мое личное мнение — использовать условное! Это намного проще понять и рассуждать. В любом случае, это выполнимо без условного оператора или троичного оператора.