我正在尝试编写一个函数,它要么接受字符串列表,要么接受单个字符串。如果它是一个字符串,那么我想把它转换成一个只有一个项的数组,这样我就可以在上面循环,而不用担心出错。

那么如何检查变量是否为数组?


当前回答

此函数将几乎所有内容转换为数组:

function arr(x) {
    if(x === null || x === undefined) {
        return [];
    }
    if(Array.isArray(x)) {
        return x;
    }
    if(isString(x) || isNumber(x)) {
        return [x];
    }
    if(x[Symbol.iterator] !== undefined || x.length !== undefined) {
        return Array.from(x);
    }
    return [x];
}

function isString(x) {
    return Object.prototype.toString.call(x) === "[object String]"
}

function isNumber(x) {
    return Object.prototype.toString.call(x) === "[object Number]"
}

它使用了一些较新的浏览器功能,因此您可能需要对其进行多填充以获得最大支持。

示例:

> arr(null);
[]
> arr(undefined)
[]
> arr(3.14)
[ 3.14 ]
> arr(1/0)
[ Infinity ]
> gen = function*() { yield 1; yield 2; yield 3; }
[Function: gen]
> arr(gen())
[ 1, 2, 3 ]
> arr([4,5,6])
[ 4, 5, 6 ]
> arr("foo")
[ 'foo' ]

N.B.字符串将被转换为具有单个元素的数组,而不是字符数组。如果您希望使用其他方式,请删除isString复选框。

我在这里使用了Array.isArray,因为它是最健壮的,也是最简单的。

其他回答

A = [1,2,3]
console.log(A.map == [].map)

为了寻找最短的版本,这是我到目前为止得到的。

注意,没有一个完美的函数能够始终检测所有可能的组合。与其期待一个神奇的工具,不如了解工具的所有能力和局限性。

这是所有方法中速度最快的(所有浏览器都支持):

function isArray(obj){
    return !!obj && obj.constructor === Array;
}

ECMAScript标准中给出的查找Object类的方法是使用Object.prototype中的toString方法。

if(Object.prototype.toString.call(someVar) === '[object Array]') {
    alert('Array!');
}

或者您可以使用typeof来测试它是否为字符串:

if(typeof someVar === 'string') {
    someVar = [someVar];
}

或者,如果您不关心性能,您可以直接连接到一个新的空数组。

someVar = [].concat(someVar);

还有可以直接查询的构造函数:

if (somevar.constructor.name == "Array") {
    // do something
}

查看T.J.Crowder的博客中的彻底治疗,如他在下面的评论中所述。

查看此基准测试,了解哪种方法性能更好:http://jsben.ch/#/QgYAV

从@Bharath,使用ES6将字符串转换为数组,以回答以下问题:

const convertStringToArray = (object) => {
   return (typeof object === 'string') ? Array(object) : object
}

假设:

let m = 'bla'
let n = ['bla','Meow']
let y = convertStringToArray(m)
let z = convertStringToArray(n)
console.log('check y: '+JSON.stringify(y)) . // check y: ['bla']
console.log('check y: '+JSON.stringify(z)) . // check y: ['bla','Meow']

您可以使用此函数获取数据类型。

var myAr = [1,2];

checkType(myAr);

function checkType(data) {
  if(typeof data ==='object') {
    if(Object.prototype.toString.call(data).indexOf('Array') !== (-1)) {
      return 'array';
    } else {
      return 'object';
    }
  } else {
    return typeof data;
  }
}

if(checkType(myAr) === 'array') {
  console.log('yes, it is an array')
};

isArray(obj)没有提供非常有用的结果。我已经创建了一个Object的原型方法,它似乎可以正确地确定和对象是否是数组。

我所知道的唯一失败的边缘情况是数组中的项设置为undefined。

Object.prototype.isArrayLike = function()
{
    var length = this.length || Object.keys(this).length;
    if (length === 0 || this.constructor.name === "String")
        return false;
    for (i = 0; i < length; i++)
    {
        if (typeof this[i] === "undefined")
            return false;
    }
    return true;
};

var arr = ['aaa', 'bbb', 'ccc', 'ddd'];
var arr1 = {"0":'aaa', "1":'bbb', 2:'ccc', 3:'ddd'};
var arr2 = {"0":'aaa', "a":'bbb', 2:'ccc', 3:'ddd'};
var arr3 = "qwerty";
var arr4 = [];
var arr5 = {0:'aaa', 1:'bbb', 2:'ccc', 3:'ddd'};

console.log("arrayLike:" + arr.isArrayLike());
console.log("Array.isArray(arr):" + Array.isArray(arr));
// arrayLike: true
// Array.isArray(arr): true
console.log("arrayLike1:" + arr1.isArrayLike());
console.log("Array.isArray(arr1):" + Array.isArray(arr1));
// arrayLike1: true
// Array.isArray(arr1): false
console.log("arrayLike2:" + arr2.isArrayLike());
console.log("Array.isArray(arr2):" + Array.isArray(arr2));
// arrayLike2: false
// Array.isArray(arr2): false
console.log("arrayLike3:" + arr3.isArrayLike());
console.log("Array.isArray(arr3):" + Array.isArray(arr3));
// arrayLike3: false
// Array.isArray(arr3): false
console.log("arrayLike4:" + arr4.isArrayLike());
console.log("Array.isArray(arr4):" + Array.isArray(arr4));
// arrayLike4: false
// Array.isArray(arr4): true
console.log("arrayLike5:" + arr5.isArrayLike());
console.log("Array.isArray(arr5):" + Array.isArray(arr5));
// arrayLike5: false
// Array.isArray(arr5): true