哈希键 / 值作为数组

65

我找不到JavaScript中与PHP的array_keys() / array_values()等价的方法。

对于不熟悉PHP的人,以下是JavaScript哈希表:

var myHash = {"apples": 3, "oranges": 4, "bananas": 42}

我怎样可以得到一个键的数组,例如:

["apples", "oranges", "bananas"]

同样的问题,但是需要提供数值:

[3, 4, 42]

可以使用jQuery。


9个回答

87
在支持 ES5 的浏览器中(或模拟)

var keys = Object.keys(myHash);

var values = keys.map(function(v) { return myHash[v]; });

MDN上的Shims...


@greg0ire:通常支持的浏览器是任何现代浏览器。一般来说,使用最多的是Chrome和Safari,Firefox 4+,Opera 10+(也许更早?)和IE9。您可以轻松地使用这两种方法来支持旧版浏览器。 - user1106925
@greg0ire:我添加了MDN提供的shim链接。 - user1106925
非常好的解决方案,但如果可能的话,代码应该兼容IE7-8。 - greg0ire
@greg0ire:包含链接的shims将使其兼容,但如果您不想要它们,则IE7/8将无法工作。 - user1106925
这个也可以: var values = keys.map(key=>myHash[key]); - Dmitry Kozlov
5
var values = Object.values(myHash); 根据 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values 进行翻译。 - konyak

53
var a = {"apples": 3, "oranges": 4, "bananas": 42};    

var array_keys = new Array();
var array_values = new Array();

for (var key in a) {
    array_keys.push(key);
    array_values.push(a[key]);
}

alert(array_keys);
alert(array_values);

9
+1,然而for循环内部的代码应该被包裹在一个检查中,以确保当前的键实际上是对象本身的属性(而不是继承属性)。否则,在IE浏览器中,您可能会得到一些意外的键:if(Object.prototype.hasOwnProperty.call(a, key)){array_keys.push(key); array_values.push(a[key]);} - JAAulde
@amnotiam在他的LINT指南中推荐使用它,网址为http://www.JSLint.com/lint.html#forin,并参考了他在http://yuiblog.com/blog/2006/09/26/for-in-intrigue/上撰写的一篇文章。 - JAAulde
@JAAulde Object.prototype中的成员应该被标记为不可枚举,并且在“foreach”中跳过,但是是的,我相信旧版IE可能会对此有问题。谢谢。 - Imp
@JAAulde:说实话,我并不在意Crockford的建议。据我所知,没有IE问题。唯一的问题是向Object.prototype添加可枚举属性,这很容易解决/撤销。 - user1106925
@Imp 是的,它们应该是兼容的,但正如你所说,IE的某些版本存在问题。如果我没记错的话,我在IE8中也遇到了这个问题,尽管可能只是在7之前。 - JAAulde
显示剩余7条评论

15

第二个答案(截至撰写本文时)给出:

var values = keys.map(function(v) { return myHash[v]; });

但我更喜欢使用jQuery自带的$.map函数:

var values = $.map(myHash, function(v) { return v; });

由于jQuery处理了跨浏览器兼容性的问题。而且它更短 :)

无论如何,我总是尽可能地保持功能性。一行代码比循环更好。


13

4
function getKeys(obj){
    var keys = [];
    for (key in obj) {
        if (obj.hasOwnProperty(key)) { keys[keys.length] = key; }
    } 
    return keys;
}

2

我不知道这是否有帮助,但“foreach”会遍历所有键:

for (var key in obj1) {...}

1
注意"jquery/prototype"风格的对象:这些库会向所有被迭代的对象添加不同的函数,就好像它们也是键一样...在这种情况下,您需要使用给定库提供的Object.each()函数: http://api.jquery.com/jQuery.each/ 有点离题,但相当重要... - Igor Deruga

1

1
你展示的函数似乎返回哈希而不是数组,或者 {0:"test"} 是 ["test"] 的同义词吗? - greg0ire

1

使用:

var myHash = {"apples": 3, "oranges": 4, "bananas": 42}
vals=(function(e){a=[];for (var i in e) a.push(e[i]); return a;})(myHash).join(',')
keys=(function(e){a=[];for (var i in e) a.push(  i ); return a;})(myHash).join(',')
console.log(vals,keys)

基本上:
array=(function(e){a=[];for (var i in e) a.push(e[i]); return a;})(HASHHERE)

-1

这里是一个来自PHP.js库的array_keys的好例子:

function array_keys (input, search_value, argStrict) {
    // Return just the keys from the input array, optionally only for the specified search_value

    var search = typeof search_value !== 'undefined',
        tmp_arr = [],
        strict = !!argStrict,
        include = true,
        key = '';

    for (key in input) {
        if (input.hasOwnProperty(key)) {
            include = true;
            if (search) {
                if (strict && input[key] !== search_value) {
                    include = false;
                }
                else if (input[key] != search_value) {
                    include = false;
                }
            }

            if (include) {
                tmp_arr[tmp_arr.length] = key;
            }
        }
    }

    return tmp_arr;
}

同样适用于array_values来自同一PHP.js库):
function array_values (input) {
    // Return just the values from the input array

    var tmp_arr = [],
        key = '';

    for (key in input) {
        tmp_arr[tmp_arr.length] = input[key];
    }

    return tmp_arr;
}

你展示的函数似乎返回哈希表而不是数组,或者{0:"test"}是["test"]的同义词吗? - greg0ire
@greg0ire 它们不是同义词。{0: "test"}Object 的一个实例,而 ["test"]Array 的一个实例。但它们都有成员 0,值为 "test" - Imp
JavaScript 中有对象和数组。你所说的哈希是一个对象。如果你看一下 var tmp_arr = [] 这一行,它表明 tmp_arr 变量是一个数组 ([]) 而不是一个对象 ({})。因此,两种方法都返回数组。 - VisioN
我是说因为你的函数似乎与Surreal Dreams提出的相同,并且他给出的链接都说这两个函数都应该返回哈希值。 - greg0ire
这是因为 PHP.js 提供的函数使用了内部方法 keys()values(),这些方法可能会返回对象,因为对于 JavaScript 迭代来说,{ 0 : 'a', 1 : 'b' }['a', 'b'] 是相同的。我已经更新了上面的函数,使它们只返回数组。 - VisioN

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