【问题标题】:How do I sort a hash table in Javascript?如何在 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 相同,使用第二个,它不会用字符串文字和大量方括号阻塞代码)

标签: javascript sorting hashtable


【解决方案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"]    

【讨论】:

    猜你喜欢
    • 2020-07-04
    • 2013-06-06
    • 2017-05-30
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    相关资源
    最近更新 更多