如何将字符串用split()方法分割成一个整数数组

17

我有一个应该被执行为数组的字符串:

var q = "The, 1, 2, Fox, Jumped, 3, Over, 4";
var z = q.split(',');

如果我使用 split(),它会创建一个字符串数组:

[‘The’, '1', '2', ‘Fox’, ‘Jumped’, '3', ‘Over’, '4'] 

而我不需要那个。我需要一个像这样的数组:

[‘The’, 1, 2, ‘Fox’, ‘Jumped’, 3, ‘Over’, 4]
指示哪个是字符串,哪个是数字。

3
快速提示:您应该按“,”拆分以获得您在问题中显示的输出。 - wizzwizz4
3
什么样的内容可以算作数字?我认为"1"不算。那么"0x3fa3"、"35e345"、"fourty-two",甚至是"čtyřicet dva"和"MCDXIII"呢? - John Dvorak
1
@wizzwizz4 - 我甚至会在 /\s*,\s* 上进行分割 - 这样无论有多少空格以及它们放置的位置都不会影响。除非对字符串的构造方式有绝对的确定性,并且它永远不会有任何其他格式。 - VLAZ
@Vld 记得加上最后的 / - wizzwizz4
1
@Vld 现在开始写回答。 - wizzwizz4
显示剩余2条评论
9个回答

17

有一种选择是使用 Number 构造函数,它返回一个数字或 NaN

var res = q.split(',').map(el => {
  let n = Number(el);
  return n === 0 ? n : n || el;
});

// > "The, 1, 2, Fox, Jumped, 3.33, Over, -0"
// < ["The", 1, 2, " Fox", " Jumped", 3.33, " Over", -0]

编辑:如果上述条件令您感到困惑,您可以将其替换为以下由Bergi建议的条件:

return isNaN(n) ? el : n;

如果您想修剪字符串元素,您也可以使用 String.prototype.trim 方法:

return isNaN(n) ? el.trim() : n;

5
这个条件真的很混乱。为什么不明确地执行 return isNaN(n) ? el : n; 呢? - Bergi

7
  1. 您可以使用Number函数将字符串化的数字转换为实际数字。
  2. 如果无法将字符串转换为数字,则Number函数将返回NaN

您可以利用这两个事实,编写类似于以下内容的代码:

"The, 1, 2, Fox, Jumped, 3, Over, 4".split(/\s*,\s*/g).map(d => Number(d) || d);
// [ 'The', 1, 2, 'Fox', 'Jumped', 3, 'Over', 4 ]

由于 NaN 是假值(Boolean(NaN) 的值为 false),如果 Number 无法将字符串转换为数字,则实际值将按原样返回。


4

//from the linked SO answer
function isNumeric(n) { 
  return !isNaN(parseFloat(n)) && isFinite(n);
}

var q = "The, 1, 2, Fox, Jumped, 3, Over, 4";
var z = q.trim().split(/\s*,\s*/).map(function(word) {
  return isNumeric(word) ? Number(word) : word;
});

console.log(z);

这是怎么回事?

isNumeric

需要注意的是,您需要一种方法来检测什么是数字,什么不是数字。我建议使用此处展示的实现方式(与我的示例相同),因为它具有稳健性并且不会产生误报或漏报。很多答案会忽略一些有效数字(例如+3-3),或将非数字的内容解析为数字(例如"")。

假设您有一个名为isNumeric()的函数,它返回一个布尔值,指示输入是否为数字。如果需要,您可能需要修改实现以适应您的需求,例如,如果您只想使用整数或只想使用正数。

分离单词

您的字符串需要被分割成单独的单词块。可以按以下方式完成:

var input = " The, 1, 2 , Fox  , Jumped  , 3, Over, 4     ";
input.trim() //make sure there are no beginning and ending spaces
    .split(/\s*,\s*/); //split on a comma surrounded by any amount of spaces. That removes spaces from start/end of each of the words
//["The", "1", "2", "Fox", "Jumped", "3", "Over", "4"]

使用 .map

map() 方法 可以作用于一个数组,将其转换为一个新的数组。这是通过使用回调函数来转换每个元素来完成的。回调函数简单地检查一个单词是否实际上是一个数字 - 如果是,它会使用Number进行显式类型转换将其解析为数字。请注意,您不应该使用 new Number(word),因为它创建了一个 Number 对象,而不是数值原始类型。

值得注意的是,可以使用 + 运算符执行隐式转换。例如:

+"500" //500
+"hello" //NaN

在我的回答开头,你可以使用+word代替Number(word),但是我认为显式转换更容易理解。


4
var q = "The, 1, 2, Fox, Jumped, 3, Over, 4";
var z = q.split(',');

您可以使用Array.map,它会返回一个新的数组。
var newAr = z.map(item => parseInt(item) ? parseInt(item) : item); 

将输出

["The", 1, 2, " Fox", " Jumped", 3, " Over", 4]

(注:该段文本为原文,无需翻译)

3
应该将 x.split(',') 改为 q.split(',')。 - Jorawar Singh
3
那么“0”呢? - str
当有前导(或尾随)空格时,parseInt(item) || 0 会产生 '0'。 - Nico
1
仍然不正确。您应该使用isNaN(..)parseInt(item)包装起来,否则当0周围有前导或尾随空格时,您最终会得到一个字符串0。 - Nico
你绝对不应该在调用 parseInt() 函数时省略第二个参数。一些浏览器可能会将输入值 0123 解释为 83 而不是预期的 123。第二个参数应该设置为 10(十进制)。此外,在 01 之间的任何输出都无法正常工作。 - Ismael Miguel

3
利用将字符串转换为数字的方法。

var q = "The, 1, 2, Fox, Jumped, 3, Over, 0";
var r = q.split`, `.map(x=>+x||x==0?+x:x);
console.log(r);


+"" //0 - 空字符串(例如输入“Hello, , world”)将被转换为零。空格也是如此(“Hello, , world”)。 - VLAZ
哦,SO的评论会删除多个空格。第二个字符串应该是“Hello, world”。 - VLAZ

3
这可以通过迭代每个数组项(通过,字符拆分)并使用map(predict)函数来实现。然后可以测试每个项是否可解析为整数。请注意保留HTML标记。
var q = "The, 1, 2, Fox, Jumped, 3, Over, 4";
var z = q.split(',').map(i => !isNaN(parseInt(i)) ? parseInt(i) : i);

高尔夫::)
p=parseInt,q="The, 0 , 2, Fox, Jumped, 3, Over, 4",z=q.split(',').map(i=>!isNaN(p(i))?p(i):i);

2
你知道有自动缩小工具,不需要自己手动操作吧? - str
1
不要忘记将基数“10”传递给parseInt函数。 - Bergi

3
我会晚一些,但我检查了所有的答案,没有一个考虑到像1.311 Balls等所有情况。此外,你没有去掉单词的额外空格,这应该被包含进来,否则我们无法得到想要的结果,就像OP请求的那样。
而且,parseFloat更好,因为你不会失去小数位。
var q = "The, 1, 2 fd, Fox, 3.12, Jumped, -3, Over, 4";

var z = q.split(',').map(function(i){
    i = i.trim();
    var reg = /^-?\d+\.?\d*$/;

    if (reg.test(i))
        return parseFloat(i);
    return i;
});

console.log(z);

结果将会是:
["The", 1, "2 fd", "Fox", 3.12, "Jumped", -3, "Over", 4]

请参见Fiddle示例

那么... 1e5 不是一个数字吗?+3 呢?0xAF呢?它们看起来很数值化。虽然它们是否对 OP 的情况有效尚未说明,但您的假设似乎在一般情况下是错误的。至少,我认为 +3 应该是一个有效的数字。 - VLAZ
这个可以很容易地改进,所以 :p - George G
可以的。我不认为为什么需要这样做 - 这是一个已解决的问题,不需要(有缺陷的)重新发明轮子。 - VLAZ
我不明白你在争论什么?而且你似乎很烦躁,我不理解你。即使接受的答案没有实现修剪,但你也没有说什么。走你自己的路吧孩子。 - George G
我没有说什么,因为我意识到指出每一个错误在一个本来不应该存在的问题上是徒劳无益的。在这里讨论的不是在JavaScript中查找数值 - 那是另一回事,并且我重申已经解决了。试图在这里重新发明它对任何人都没有好处 - 在最好的情况下,他们成功了,这几乎没有任何作用。在最坏的情况下,他们失败并误导某人犯错。无论哪种方式 - 这种努力都是浪费的。 - VLAZ

2

我尝试使用forEach循环,通过isNaN:如果不是数字则返回true,如果是数字则返回false检查是否为数字,并将其推入新数组中...

var q = "The, 1, 2, Fox, Jumped, 3, Over, 4";
var z = [];
q.split(',').forEach(function(v,k){
       isNaN(v) ? z.push(v) : z.push(parseInt(v));
});
console.log(z);

为什么不直接使用 .map() 呢?它的作用与 "forEach 然后将内容推送至新数组" 相同,只是你不需要创建数组或者其他任何东西。使用 .map() 更容易进行数组转换操作。另外,如果你不打算使用键值,为什么还要在回调函数中获取键值呢? - VLAZ

2
你可以使用 for..of 循环,.test() 函数,并将 /\d/ 作为参数。
var res = []; for (p of q.split(",")) [...res] = [...res, /\d/.test(p) ? +p : p];

“10”,“-1”,“3.14”(以及其他一些)似乎不是数字。 - VLAZ
@Vld "10、-1、3.14(等等)似乎不是数字。" 不确定您的意思?https://jsfiddle.net/t8wv1kqs/ - guest271314

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接