Преобразовать строковый параметр в массив из одного элемента - PullRequest
0 голосов
/ 04 января 2019

Я написал функцию, которая должна поддерживать два типа параметра names для списка значений. Внутренне он имеет дело с параметром в виде массива.

Одно имя задается в виде строки, а кратные имена - в виде массива строк.

// simplified example
let doSome =  names => names.map(name => name.toUpperCase())

names(['Bart', 'Lisa'])
// [ 'BART', 'LISA' ]
names('Homer')
// TypeError: names.map is not a function

Я нашел решение, используя Array.of() в сочетании с flatten(), для которого требуется некоторая конфигурация babel.

doSome = names => Array.of(names).flatten().map(name => name.toUpperCase());

Есть ли в JavaScript идиоматический способ получить массив без проверки типа?

Ответы [ 4 ]

0 голосов
/ 08 января 2019

Почему бы просто не проверить, является ли ввод массивом или не используется isArray () ?

Я принял другое решение, используя этот подход, а также поместил элемент управления в map(), чтобы он не завершился ошибкой, если аргумент name равен null или undefined.

const names = x => (Array.isArray(x) ? x : [x]).map(name => name && name.toUpperCase());

console.log(JSON.stringify( names(['Bart', 'Lisa']) ));
console.log(JSON.stringify( names('Homer') ));
console.log(JSON.stringify( names('') ));
console.log(JSON.stringify( names(null) ));
console.log(JSON.stringify( names([null]) ));
console.log(JSON.stringify( names([undefined, "Roger", "Bob", null]) ));
0 голосов
/ 04 января 2019

Может быть, в этом случае поможет следующий метод Array#flat (фактически работает только в Chrome и FF).

const names = unknown => [unknown].flat().map(name => name.toUpperCase())

console.log(names(['Bart', 'Lisa']));
console.log(names('Homer'));
0 голосов
/ 04 января 2019

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

Это означает, что вы можете вызвать функцию как names('Homer') или names('Bart', 'Lisa'):

function names(...args){
  return args.map(name => name.toUpperCase());
}

console.log(names('Bart', 'Lisa')); // [ 'BART', 'LISA' ]
console.log(names('Homer')); // ['HOMER']

Если вы действительно хотите вызывать функцию с массивом в качестве аргумента, вы можете использовать синтаксис :

console.log(names(...['Bart', 'Lisa'])); // [ "BART", "LISA" ]

Если вы используете его со строкой, вы получите массив символов, однако:

console.log(names(...'Homer')); // [ "H", "O", "M", "E", "R" ]
0 голосов
/ 04 января 2019

Вы можете использовать Array.concat(), так как concat принимает как массивы, так и не массивы:

const names = (v) => [].concat(v).map(name => name.toUpperCase())

console.log(names(['Bart', 'Lisa'])) // [ 'BART', 'LISA' ]
console.log(names('Homer')) // ['HOMER']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...