如何在 Javascript 中对哈希表进行排序?

Posted

技术标签:

【中文标题】如何在 Javascript 中对哈希表进行排序?【英文标题】:How do I sort a hash table in Javascript? 【发布时间】:2011-02-17 01:59:03 【问题描述】:

我有一个 javascript 哈希表,如下所示:

var things = [ ];
things["hello"] = "name" : "zzz I fell asleep", "number" : 7;
things["one"] = "name" : "something", "number" : 18;
things["two"] = "name" : "another thing", "number" : -2;

我想按名称对它们进行排序,所以如果我遍历哈希表,它将按顺序排列

another thing
something
zzz I fell asleep

我试过这样做:

function compareThings(thing1, thing2) 
    var name1 = thing1["name"].toLowerCase();
    var name2 = thing2["name"].toLowerCase();
    if (name1 < name2) 
        return -1;
        
    if (name1 > name2) 
        return 1;
        
    return 0;


things.sort(compareThings);

但它似乎不起作用。

编辑:在我看来,排序的哈希表可能是矛盾的。如果是这样,访问此处的排序列表的最佳方式是什么?

【问题讨论】:

你没有一个 hastable (aka object) 也没有一个合适的数组。如果你想要一个对象,你应该用而不是[]来初始化它。如果您使用[] 进行初始化,则您有一个数组,但不要通过a["one"]a["two"] 而是通过a.push(...); 添加到它。只有知道自己想要什么数据结构后,才可以费心去排序。 (顺便说一句:foo["bar"]foo.bar 相同,使用第二个,它不会用字符串文字和大量方括号阻塞代码) 【参考方案1】:

如果您想按顺序遍历 JavaScript 中的哈希表,请创建一个数组,用哈希键填充它,然后对其进行排序。

<html>
<body>
<pre>
  <script>
    var things = new Object ();
    things["hello"] = "name" : "zzz I fell asleep", "number" : 7;
    things["one"] = "name" : "something", "number" : 18;
    things["two"] = "name" : "another thing", "number" : -2;
    var keys = [];
    for (var key in things) 
      if (things.hasOwnProperty(key)) 
        keys.push(key);
      
    
    keys.sort ();
    for (i in keys) 
      var key = keys[i];
      var value = things[key];
      document.write (key +"="+value+"\n");
    
  </script>
</pre>
</body>
</html>

【讨论】:

请注意,for...in 语句的迭代顺序可以是任意的,ECMAScript specification 中没有描述属性的枚举顺序,它取决于实现。 . 没有保证,请谨慎使用... @CMS:所以我应该使用for (var i = 0; i &lt; keys.length; i++) 来严格正确? @Kinopiko,确切地说,请查看以下文章以获取更多信息:[ 1 ](andrewdupont.net/2006/05/18/…) 和 [ 2 ](dhtmlkitchen.com/?category=/JavaScript/&date=2007/10/21/…)。 您也可以使用Object.keys(things) 构建您的keys 数组。在 for 循环的比较步骤之前存储数组长度也是一个好习惯,因此上面的 @CMS 的 for 循环可以写成 for (var i = 0, l = keys.length; i &lt; l; i++)。这样可以避免重复索引到 keys.length 属性以获取不变的值。【参考方案2】:

我的解决方案

things.sort(function(a,b)return a.name - b.name;);

【讨论】:

OP 使用数组 things 不正确,所以这无济于事。【参考方案3】:

我开发了一个函数,它通过键对哈希表进行排序,无论值是数字还是字符串。如果表是关联表,则保留密钥。

function sortHashTableByKey(hash, key_order, remove_key)

    var tmp = [],
        end = [],
        f_order = null;
    remove_key = remove_key || false;
    for (var key in hash)
    
        if (hash.hasOwnProperty(key))
        
            tmp.push(hash[key][key_order]);
        
    
    if (hash && hash[0] && typeof(hash[0][key_order]) === 'number')
    
        f_order = function (a, b)  return a - b; ;
    
    tmp.sort(f_order);
    function getHash(hash, value)
    
        for (k in hash)
        
            if (hash[k] && hash[k][key_order] === value)
            
                return  key : k, hash : hash[k] ;
            
        
    
    for (var i = 0, l = tmp.length; i < l; i++)
    
        tmp[i] = getHash(hash, tmp[i]);
        if (remove_key)
        
            delete tmp[i].hash[key_order];
        
        if (!hash.length)
        
            end[tmp[i].key] = tmp[i].hash;
        
        else
        
            end.push(tmp[i].hash);
        
    
    return end;

这样就可以了:

var things = new Object ();
things["hello"] = "name" : "zzz I fell asleep", "number" : 7;
things["one"] = "name" : "something", "number" : 18;
things["two"] = "name" : "another thing", "number" : -2;

things = sortHashTableByKey(things, 'name');

/*
[
  two:  name: 'another thing', number: -2 ,
  one:  name: 'something', number: 18 ,
  hello:  name: 'zzz I fell asleep', number: 7 
]
*/

【讨论】:

@HaykSaakian,该功能进展如何?作为一个人,我真的很钦佩任何人在超越身心问题的同时维持状态和功能的努力。太棒了。 我应该说“做这个”而不是“成为这个”@ToddMorrison【参考方案4】:

您的参数是thing1thing2,但您引用了一些名为asp1asp2 的变量,据我从您提供的来源可以看出,这些变量不存在。

另外,我认为您正在寻找的是一个关联数组,它不是用[] 语法实例化的。请参阅此处了解更多信息:

http://www.quirksmode.org/js/associative.html

编辑:我不认为 Javascript 中有一个数组可以让你做你想做的事。

你可以有一个普通的旧数组,它可以让你进行自定义排序或者你可以有一个关联数组,它可以让你有命名的值。

使用常规数组,您显然可以遍历索引。

使用关联数组,您可以通过 for (var key in myArray) 遍历名称

【讨论】:

小心 for...in 语法。它将遍历所有相关对象具有的属性,其中包括数组键以外的内容。 ^^ 这是真的,但只要它不从任何东西继承就应该不是问题。【参考方案5】:

与eeerahul相同,带有keys()和String().localeCompare():

function sort_by_key(t_kv,v_kv)
  return(Object.keys(t_kv).sort(
    function(a,b)return(
      String(t_kv[a][v_kv]).localeCompare(String(t_kv[b][v_kv])))))


t=two:s:'two',n:2,three:s:'three',n:3,one:s:'one',n:1
sort_by_key(t,'n')
    ["one", "two", "three"]
sort_by_key(t,'s')
    ["one", "three", "two"]    

【讨论】:

以上是关于如何在 Javascript 中对哈希表进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

在 awk 中对哈希/数组进行排序

PowerShell对象排序(结合哈希表)

如何在 JavaScript 中对字符串进行排序

如何在javascript中对多维数组进行排序

如何在javascript中对嵌套的对象数组进行排序?

如何在javascript中对字母数字数组进行排序[重复]