преобразовать строку в массив целых чисел

92

Я хочу преобразовать следующую строку '14 2'в массив из двух целых чисел. Как я могу это сделать ?

TJ
источник

Ответы:

88

Вы можете .split()получить массив строк , а затем выполнить цикл для преобразования их в числа, например:

var myArray = "14 2".split(" ");
for(var i=0; i<myArray.length; i++) { myArray[i] = +myArray[i]; } 
//use myArray, it's an array of numbers

Это +myArray[i]просто быстрый способ выполнить преобразование чисел, если вы уверены, что они целые числа, вы можете просто сделать:

for(var i=0; i<myArray.length; i++) { myArray[i] = parseInt(myArray[i], 10); } 
Ник Крейвер
источник
5
короче: for(var i=myArray.length; i--;) myArray[i] = myArray[i]|0;с использованием побитового преобразования и более короткого цикла
vsync 08
1
или с ES5:myArray.forEach(function(x,y,z){ z[y]=x|0 })
vsync 08
3
@vsync - конечно ... но когда какой-либо компилятор собирается сократить его еще больше, зачем делать его поддержку? :) Ясность стоит нескольких дополнительных байтов, особенно если на самом деле она не будет намного длиннее, если ее когда-то минимизировать.
Ник Крейвер
потому что на этот раз я не уменьшаю свой опубликованный код, чтобы другие могли читать мой код и видеть, что происходит, а во-вторых, побитовые операции намного быстрее, чем parseInt.
vsync 09
5
@vsync - убедитесь, что вы проверили это утверждение во всех браузерах, я лично считаю, что знак + более читабелен ... и если вы проверите, в большинстве последних браузеров разница в любом случае незначительна - в зависимости от движка. Кроме того, вы можете предложить, .min.jsи .jsесли вы хотите раскрыть свой код ... помните, что минификация не для неясности (или не должна быть, так как она бесполезна для этого), это для уменьшения накладных расходов HTTP - более быстрой загрузки страницы для ваших пользователей.
Ник Крейвер
213

Быстрый вариант для современных браузеров:

'14 2'.split(' ').map(Number);

// [14, 2]`
xer0x
источник
1
Очень чистый способ! Должно быть наверху.
лесной орех
1
мячи. это потрясающе. такой свежий и такой чистый.
Тодд
2
+1 и просто добавьте polyfill для поддержки старых браузеров, если требуется developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
qdev
1
хорошо, но как это на самом деле работает? Вы передаете объект Number, но я не уверен, как он его конвертирует. Я думал, вам нужно передать функцию для сопоставления.
Jarg7
2
да, верно. Number () - это функция, переданная в map, и она преобразует значения. Ознакомьтесь с ответом Тодда для получения более подробной информации.
xer0x 09
35

ТАК ... старая ветка, я знаю, но ...

РЕДАКТИРОВАТЬ

@RoccoMusolino неплохо уловил; вот альтернатива:

TL; DR:

 const intArray = [...("5 6 7 69 foo 0".split(' ').filter(i => /\d/g.test(i)))]

НЕПРАВИЛЬНО :"5 6 note this foo".split(" ").map(Number).filter(Boolean); // [5, 6]

Есть тонкий недостаток в более элегантных решениях, перечисленных здесь, в частности, в красивых ответах @amillara и @Marcus.

Проблема возникает, когда элемент массива строк не является целочисленным, возможно, в случае без проверки на входе. Для надуманного примера ...

Проблема:


var effedIntArray = "5 6 7 69 foo".split(' ').map(Number); // [5, 6, 7, 69, NaN]

Поскольку вам, очевидно, нужен массив PURE int, это проблема. Честно говоря , я этого не заметил, пока не скопировал код SO в свой скрипт ...: /


(Чуть-менее Baller) Исправление:


var intArray = "5 6 7 69 foo".split(" ").map(Number).filter(Boolean); // [5, 6, 7, 69]

Итак, теперь, даже когда у вас есть дерьмовая строка int, ваш вывод представляет собой чистый целочисленный массив. Остальные в большинстве случаев действительно сексуальны, но на самом деле я действительно хотел предложить свои в основном бессвязные выступления . Хотя, надо отдать должное, это все еще однострочный ...

Надеюсь, это кому-то сэкономит время!

Тодд
источник
1
Totes baller мне хватит. Спасибо, Тодд!
indextwo 02
5
Будьте осторожны, это не сработает, если ваша строка содержит один или несколько 0. Ноль переводится в логическое значение = ложь, поэтому логический фильтр не сохранит его.
Рокко Мусолино
1
можно заменить .filter(Boolean)на.filter( (x) => !Number.isNaN(x))
Bob9630 05
26
var result = "14 2".split(" ").map(function(x){return parseInt(x)});
амиллара
источник
5
Не все браузеры поддерживают это - это не работает в IE, это функция JavaScript 1.6+. Кроме того, я сказал в другом ответе, всегда передавайте основание parseInt().
Ник Крейвер
2
Я так с нетерпением жду, когда мы сможем использовать .mapи подобное в JS в любом браузере без дополнительных библиотек.
JAL
5

Альтернативой ответу Тушара Гупты было бы:

'14 2'.split(' ').map(x=>+x);

// [14, 2]`

В коде гольф вы сохраняете 1 символ. Здесь «+» - это оператор «унарный плюс», работает как parseInt.

Ян Роллан
источник
3

Сначала разделите строку на пробелы:

var result = '14 2'.split(' ');

Затем преобразуйте результирующий массив строк в целые числа:

for (var i in result) {
    result[i] = parseInt(result[i], 10);
}
Маркус Уайброу
источник
2
Вы всегда должны передавать аргумент radix parseInt(), иначе вы можете получить восьмеричные числа.
Ник Крейвер
Если строки не начинаются с 0, или 0xвсе должно быть в порядке.
Маркус Уайброу,
1
Если они этого не делают (видите, как вы снабдили это предположением?) ... зачем добавлять 3 символа, которые необходимы, чтобы сделать это правильным и для всех этих случаев?
Ник Крейвер
3

Пункт против parseIntподхода:

Нет необходимости использовать лямбды и / или указывать radixпараметр parseInt, просто используйте parseFloatили Numberвместо них.


Причины:

  1. Это работает:

    var src = "1,2,5,4,3";
    var ids = src.split(',').map(parseFloat); // [1, 2, 5, 4, 3]
    
    var obj = {1: ..., 3: ..., 4: ..., 7: ...};
    var keys= Object.keys(obj); // ["1", "3", "4", "7"]
    var ids = keys.map(parseFloat); // [1, 3, 4, 7]
    
    var arr = ["1", 5, "7", 11];
    var ints= arr.map(parseFloat); // [1, 5, 7, 11]
    ints[1] === "5" // false
    ints[1] === 5   // true
    ints[2] === "7" // false
    ints[2] === 7   // true
    
  2. Это короче.

  3. Это немного быстрее и использует кеш, когда parseInt-approach - нет :

      // execution time measure function
      // keep it simple, yeah?
    > var f = (function (arr, c, n, m) {
          var i,t,m,s=n();
          for(i=0;i++<c;)t=arr.map(m);
          return n()-s
      }).bind(null, "2,4,6,8,0,9,7,5,3,1".split(','), 1000000, Date.now);
    
    > f(Number) // first launch, just warming-up cache
    > 3971 // nice =)
    
    > f(Number)
    > 3964 // still the same
    
    > f(function(e){return+e})
    > 5132 // yup, just little bit slower
    
    > f(function(e){return+e})
    > 5112 // second run... and ok.
    
    > f(parseFloat)
    > 3727 // little bit quicker than .map(Number)
    
    > f(parseFloat)
    > 3737 // all ok
    
    > f(function(e){return parseInt(e,10)})
    > 21852 // awww, how adorable...
    
    > f(function(e){return parseInt(e)})
    > 22928 // maybe, without '10'?.. nope.
    
    > f(function(e){return parseInt(e)})
    > 22769 // second run... and nothing changes.
    
    > f(Number)
    > 3873 // and again
    > f(parseFloat)
    > 3583 // and again
    > f(function(e){return+e})
    > 4967 // and again
    
    > f(function(e){return parseInt(e,10)})
    > 21649 // dammit 'parseInt'! >_<
    

Примечание: в Firefox parseIntработает примерно в 4 раза быстрее, но все же медленнее других. В общей сложности: +e< Number< parseFloat<parseInt

анхзет
источник
0

Просто ради забавы подумал, что тоже добавлю forEach(f())решение.

var a=[];
"14 2".split(" ").forEach(function(e){a.push(parseInt(e,10))});

// a = [14,2]
окодо
источник
0
let idsArray = ids.split(',').map((x) => parseInt(x));
Ахмед Саид
источник
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшило бы долгосрочную ценность ответа.
Badacadabra
0

Лучшее однострочное решение:

var answerInt = [];
var answerString = "1 2 3 4";
answerString.split(' ').forEach(function (item) {
   answerInt.push(parseInt(item))
});
Рави Гаур
источник
Это не строка.
delroh 05
-3

нам функция разделения :

var splitresult = "14 2".split(" ");
Pyvi
источник
3
Это получает массив строк, а не чисел.
Ник Крейвер
Ой, да, это неправильно. Тогда см. Ответ Маркуса Уайброу или Ника Крейвера, чтобы узнать остальное.
pyvi