Как безопасно преобразовать строку через запятую в массив чисел - PullRequest
3 голосов
/ 21 мая 2019

Редактировать :

Почему это не дубликат

Этот вопрос специально решает проблему, заключающуюся в том, что пустые строки и любое количество пробелов преобразуются в 0 с использованием Number(str).

Взгляните на следующий фрагмент:

convertBtn.addEventListener('click', () => console.log(toArrayOfNumber(foo.value)))

const toArrayOfNumber = str => str.split(',').map(Number);
<input type="text" id="foo" value="1,2,4,-1" />
<button type="button" id="convertBtn">convert to array of numbers</button>

Пока вход имеет правильный value, все работает нормально. Теперь я хочу сделать его отказоустойчивым для следующих значений:

  • ,
  • , ,,

То, что застало меня врасплох, это то, что Number("") и Number(" ") оба возвращают 0 (что я не хочу, так как для моего сценария использования я не хочу, чтобы "" или любое количество пробелов считалось a Number).

Итак, я придумал это:

convertBtn.addEventListener('click', () => console.log(toArrayOfNumber(foo.value)))

const toArrayOfNumber = str => str.split(',').filter(x => x.trim() !== "").map(Number);
<input type="text" id="foo" value="1,2,4,-1,,, ,, 11" />
<button type="button" id="convertBtn">convert to array of numbers</button>

Это неловко, я надеюсь, что есть очевидное и лучшее решение, которого я не вижу.

Ответы [ 4 ]

2 голосов
/ 21 мая 2019

Если вы имеете дело только с целыми числами, будет работать и следующее.0 будут сохранены, но пустые значения будут удалены.

split(',').filter(num => !isNaN(parseInt(num))).map(Number);

Пример

const str = '1,2,4,-1,,, ,0, 11';

console.log(str.split(',').filter(num => !isNaN(parseInt(num))).map(Number));
2 голосов
/ 21 мая 2019

Ответ от @KendallFrey (который отказывается публиковать сообщения, поэтому я краду его решение)

'1,2,4,-1,,, ,, 11,0,0'.split(/[, ]+/).map(x=>+x)

Вы все еще можете использовать .map(Number), но x=>+x на 1 байт короче.

Результаты в консоли: (7) [1, 2, 4, -1, 11, 0, 0]

Другое решение регулярных выражений (не допускающее десятичные дроби): /-?\d+/g

1 голос
/ 21 мая 2019

Вы также можете сделать это через Array.reduce, где на каждой итерации вы проверяете с помощью isNaN для parseInt:

let data = "1,2,4,-1,,, ,0, 11"

let r = data.split(',').reduce((r,c) => isNaN(parseInt(c)) ? r : [...r, +c],[])

console.log(r)

Таким образом, вы только iterate over the array once после разделения. Кроме того, это позволит сохранить нули нетронутыми и просто отбросить все не числа.

1 голос
/ 21 мая 2019

Попробуйте это:

const value="-99,1,2,4,-1,,, ,0,, 11"
const toArrayOfNumber = str => str.split(',').map(num => num.trim() && Number(num)).filter(num => !Number.isNaN(num) && typeof num != 'string');

const nums = toArrayOfNumber(value);

nums.forEach(num => console.log(typeof num, num));

Мы используем результаты trim, чтобы определить, должны ли мы обрабатывать его как число. Если нет, то у нас просто есть string, и это отфильтровано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...