关于排序:按键对javascript对象排序

Sort JavaScript object by key

我需要按键对javascript对象进行排序。

因此,以下内容:

1
{ 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' }

将成为:

1
{ 'a' : 'dsfdsfsdf', 'b' : 'asdsad', 'c' : 'masdas' }


这个问题的其他答案已经过时了,从来没有与实现的实际情况相匹配,并且由于ES6/ES2015规范已经发布,正式变得不正确。

参见Axel Rauschmayer在探索ES6中关于属性迭代顺序的章节:

All methods that iterate over property keys do so in the same order:

  • First all Array indices, sorted numerically.
  • Then all string keys (that are not indices), in the order in which they were created.
  • Then all symbols, in the order in which they were created.
  • 所以是的,事实上,javascript对象是按顺序排列的,它们的键/属性的顺序可以更改。

    以下是如何按对象的键/属性按字母顺序对其排序:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    const unordered = {
      'b': 'foo',
      'c': 'bar',
      'a': 'baz'
    };

    console.log(JSON.stringify(unordered));
    // → '{"b":"foo","c":"bar","a":"baz"}'

    const ordered = {};
    Object.keys(unordered).sort().forEach(function(key) {
      ordered[key] = unordered[key];
    });

    console.log(JSON.stringify(ordered));
    // → '{"a":"baz","b":"foo","c":"bar"}'

    为了与ES5发动机兼容,使用var而不是const


    javascript对象1未排序。试图"分类"它们是毫无意义的。如果要迭代对象的属性,可以对键进行排序,然后检索关联的值:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    var myObj = {
        'b': 'asdsadfd',
        'c': 'masdasaf',
        'a': 'dsfdsfsdf'
      },
      keys = [],
      k, i, len;

    for (k in myObj) {
      if (myObj.hasOwnProperty(k)) {
        keys.push(k);
      }
    }

    keys.sort();

    len = keys.length;

    for (i = 0; i < len; i++) {
      k = keys[i];
      console.log(k + ':' + myObj[k]);
    }

    使用Object.keys风扇的替代实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var myObj = {
        'b': 'asdsadfd',
        'c': 'masdasaf',
        'a': 'dsfdsfsdf'
      },
      keys = Object.keys(myObj),
      i, len = keys.length;

    keys.sort();

    for (i = 0; i < len; i++) {
      k = keys[i];
      console.log(k + ':' + myObj[k]);
    }

    1不要学究,但没有JSON对象这样的东西。


    很多人都提到"对象不能排序",但在那之后他们会给你一个有效的解决方案。悖论,不是吗?

    没有人提到这些解决方案为什么有效。它们是,因为在大多数浏览器的实现中,对象中的值按添加顺序存储。这就是为什么如果从已排序的键列表中创建新对象,它将返回预期的结果。

    我认为我们可以再添加一个解决方案——ES5功能方式:

    1
    2
    3
    4
    5
    6
    function sortObject(obj) {
        return Object.keys(obj).sort().reduce(function (result, key) {
            result[key] = obj[key];
            return result;
        }, {});
    }

    以上ES2015版本(格式为"一行"):

    1
    2
    3
    function sortObject(o) {
        return Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {});
    }

    上述例子的简短解释(如评论中所要求的):

    Object.keys向我们提供了一个所提供对象(objo中的键列表),然后我们使用默认排序算法对这些键进行排序,接下来使用.reduce将该数组转换回一个对象,但这次所有键都进行了排序。


    这对我有用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
     * Return an Object sorted by it's Key
     */

    var sortObjectByKey = function(obj){
        var keys = [];
        var sorted_obj = {};

        for(var key in obj){
            if(obj.hasOwnProperty(key)){
                keys.push(key);
            }
        }

        // sort keys
        keys.sort();

        // create new array based on Sorted Keys
        jQuery.each(keys, function(i, key){
            sorted_obj[key] = obj[key];
        });

        return sorted_obj;
    };


    伙计们,我很震惊!当然,所有的答案都有点老套,但没有人提到排序的稳定性!所以,请放心,我会尽力回答这个问题,并在这里详细讨论。所以我要道歉了,现在要读很多东西。

    由于是2018年,我将只使用ES6,Polyfills在MDN文档中都可用,我将在给定的部分链接。

    回答问题:

    如果您的密钥只是数字,那么您可以安全地使用Object.keys()Array.prototype.reduce()返回排序对象:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // Only numbers to show it will be sorted.
    const testObj = {
      '2000': 'Articel1',
      '4000': 'Articel2',
      '1000': 'Articel3',
      '3000': 'Articel4',
    };

    // I'll explain what reduces does after the answer.
    console.log(Object.keys(testObj).reduce((accumulator, currentValue) => {
      accumulator[currentValue] = testObj[currentValue];
      return accumulator;
    }, {}));

    /**
     * expected output:
     * {
     * '1000': 'Articel3',
     * '2000': 'Articel1',
     * '3000': 'Articel4',
     * '4000': 'Articel2'
     *  }
     */


    // if needed here is the one liner:
    console.log(Object.keys(testObj).reduce((a, c) => (a[c] = testObj[c], a), {}));

    但是,如果您使用的是字符串,我强烈建议将Array.prototype.sort()链接到所有这些内容中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // String example
    const testObj = {
      'a1d78eg8fdg387fg38': 'Articel1',
      'z12989dh89h31d9h39': 'Articel2',
      'f1203391dhj32189h2': 'Articel3',
      'b10939hd83f9032003': 'Articel4',
    };
    // Chained sort into all of this.
    console.log(Object.keys(testObj).sort().reduce((accumulator, currentValue) => {
      accumulator[currentValue] = testObj[currentValue];
      return accumulator;
    }, {}));

    /**
     * expected output:  
     * {
     * a1d78eg8fdg387fg38: 'Articel1',
     * b10939hd83f9032003: 'Articel4',
     * f1203391dhj32189h2: 'Articel3',
     * z12989dh89h31d9h39: 'Articel2'
     * }
     */


    // again the one liner:
    console.log(Object.keys(testObj).sort().reduce((a, c) => (a[c] = testObj[c], a), {}));

    如果有人想知道什么是减少:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // Will return Keys of object as an array (sorted if only numbers or single strings like a,b,c).
    Object.keys(testObj)

    // Chaining reduce to the returned array from Object.keys().
    // Array.prototype.reduce() takes one callback
    // (and another param look at the last line) and passes 4 arguments to it:
    // accumulator, currentValue, currentIndex and array
    .reduce((accumulator, currentValue) => {

      // setting the accumulator (sorted new object) with the actual property from old (unsorted) object.
      accumulator[currentValue] = testObj[currentValue];

      // returning the newly sorted object for the next element in array.
      return accumulator;

      // the empty object {} ist the initial value for  Array.prototype.reduce().
    }, {});

    如果需要,这里是一个衬里的说明:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Object.keys(testObj).reduce(

      // Arrow function as callback parameter.
      (a, c) =>

      // parenthesis return! so we can safe the return and write only (..., a);
      (a[c] = testObj[c], a)

      // initial value for reduce.
      ,{}
    );
    • Reduce文档:https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/array/reduce
    • 为什么在javascript返回语句中使用括号:http://jamesknelson.com/javascript-return-bortis/

    为什么排序有点复杂:

    简而言之,Object.keys()将返回一个数组,其顺序与正常循环相同:

    1
    2
    3
    4
    5
    6
    7
    8
    const object1 = {
      a: 'somestring',
      b: 42,
      c: false
    };

    console.log(Object.keys(object1));
    // expected output: Array ["a","b","c"]

    Object.keys() returns an array whose elements are strings
    corresponding to the enumerable properties found directly upon object.
    The ordering of the properties is the same as that given by looping
    over the properties of the object manually.

    • https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/object/keys

    旁注-您也可以在数组上使用Object.keys(),请记住,索引将返回:

    1
    2
    3
    // simple array
    const arr = ['a', 'b', 'c'];
    console.log(Object.keys(arr)); // console: ['0', '1', '2']

    但这些例子显示的并不容易,现实世界中的对象可能包含数字、字母字符甚至符号(请不要这样做)。

    下面是一个例子,其中所有这些都在一个对象中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // This is just to show what happens, please don't use symbols in keys.
    const testObj = {
      '1asc': '4444',
      1000: 'a',
      b: '1231',
      '#01010101010': 'asd',
      2: 'c'
    };

    console.log(Object.keys(testObj));
    // output: [ '2', '1000', '1asc', 'b', '#01010101010' ]

    现在,如果我们在上面的数组上使用Array.prototype.sort(),输出会发生变化:

    1
    2
    console.log(Object.keys(testObj).sort());
    // output: [ '#01010101010', '1000', '1asc', '2', 'b' ]

    以下是这些文件的报价:

    The sort() method sorts the elements of an array in place and returns
    the array. The sort is not necessarily stable. The default sort order
    is according to string Unicode code points.

    The time and space complexity of the sort cannot be guaranteed as it
    is implementation dependent.

    • https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/array/sort

    您必须确保其中一个为您返回所需的输出。在现实生活的例子中,如果将不同的信息输入(如API和数据库)一起使用,人们往往会把事情搞混。

    那有什么大不了的?

    每个程序员都应该理解两篇文章:

    就地算法:

    In computer science, an in-place algorithm is an algorithm which transforms input using no auxiliary data structure. However a small amount of extra storage space is allowed for auxiliary variables. The input is usually overwritten by the output as the algorithm executes. In-place algorithm updates input sequence only through replacement or swapping of elements. An algorithm which is not in-place is sometimes called not-in-place or out-of-place.

    所以基本上我们的旧数组将被覆盖!如果出于其他原因要保留旧数组,这一点很重要。所以记住这一点。

    排序算法

    Stable sort algorithms sort identical elements in the same order that
    they appear in the input. When sorting some kinds of data, only part
    of the data is examined when determining the sort order. For example,
    in the card sorting example to the right, the cards are being sorted
    by their rank, and their suit is being ignored. This allows the
    possibility of multiple different correctly sorted versions of the
    original list. Stable sorting algorithms choose one of these,
    according to the following rule: if two items compare as equal, like
    the two 5 cards, then their relative order will be preserved, so that
    if one came before the other in the input, it will also come before
    the other in the output.

    enter image description here

    An example of stable sort on playing cards. When the cards are sorted
    by rank with a stable sort, the two 5s must remain in the same order
    in the sorted output that they were originally in. When they are
    sorted with a non-stable sort, the 5s may end up in the opposite order
    in the sorted output.

    这表明排序是正确的,但它改变了。所以在现实世界中,即使排序是正确的,我们也必须确保我们得到我们期望的!这是非常重要的,请记住这一点。有关更多的javascript示例,请查看array.prototype.sort()-docs:https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/array/sort


    这是一个古老的问题,但从Mathias Bynens的回答中可以看出,我做了一个简短的版本来对当前对象进行排序,没有太多开销。

    1
    2
    3
    4
    5
        Object.keys(unordered).sort().forEach(function(key) {
            var value = unordered[key];
            delete unordered[key];
            unordered[key] = value;
        });

    代码执行之后,"无序"对象本身将按字母顺序对键进行排序。


    使用火山灰可以:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    some_map = { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' }

    // perform a function in order of ascending key
    _(some_map).keys().sort().each(function (key) {
      var value = some_map[key];
      // do something
    });

    // or alternatively to build a sorted list
    sorted_list = _(some_map).keys().sort().map(function (key) {
      var value = some_map[key];
      // return something that shall become an item in the sorted list
    }).value();

    只是思考的食物。


    这是1号班轮

    1
    2
    3
    4
    5
    6
    7
    8
    var data = { zIndex:99,
                 name:'sravan',
                 age:25,
                 position:'architect',
                 amount:'100k',
                 manager:'mammu' };

    console.log(Object.entries(data).sort().reduce( (o,[k,v]) => (o[k]=v,o), {} ));


    假设它在显示无序对象属性的VisualStudio调试器中很有用。

    1
    (function(s){var t={};Object.keys(s).sort().forEach(function(k){t[k]=s[k]});return t})({b:2,a:1,c:3})


    下划线版本:

    1
    2
    3
    4
    function order(unordered)
    {
    return _.object(_.sortBy(_.pairs(unordered),function(o){return o[0]}));
    }

    如果您不信任浏览器来保持键的顺序,我强烈建议您依赖键值对数组的有序数组。

    1
    _.sortBy(_.pairs(c),function(o){return o[0]})


    也许更优雅一点:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     /**
         * Sorts a key-value object by key, maintaining key to data correlations.
         * @param {Object} src  key-value object
         * @returns {Object}
         */

    var ksort = function ( src ) {
          var keys = Object.keys( src ),
              target = {};
          keys.sort();
          keys.forEach(function ( key ) {
            target[ key ] = src[ key ];
          });
          return target;
        };


    // Usage
    console.log(ksort({
      a:1,
      c:3,
      b:2  
    }));

    P.S.和ES6+语法相同:

    1
    2
    3
    4
    5
    6
    7
    8
    function ksort( src ) {
      const keys = Object.keys( src );
      keys.sort();
      return keys.reduce(( target, key ) => {
            target[ key ] = src[ key ];
            return target;
      }, {});
    };


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function sortObjectKeys(obj){
        return Object.keys(obj).sort().reduce((acc,key)=>{
            acc[key]=obj[key];
            return acc;
        },{});
    }

    sortObjectKeys({
        telephone: '069911234124',
        name: 'Lola',
        access: true,
    });


    递归排序,用于嵌套对象和数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    function sortObjectKeys(obj){
        return Object.keys(obj).sort().reduce((acc,key)=>{
            if (Array.isArray(obj[key])){
                acc[key]=obj[key].map(sortObjectKeys);
            }
            if (typeof obj[key] === 'object'){
                acc[key]=sortObjectKeys(obj[key]);
            }
            else{
                acc[key]=obj[key];
            }
            return acc;
        },{});
    }

    // test it
    sortObjectKeys({
        telephone: '069911234124',
        name: 'Lola',
        access: true,
        cars: [
            {name: 'Family', brand: 'Volvo', cc:1600},
            {
                name: 'City', brand: 'VW', cc:1200,
                interior: {
                    wheel: 'plastic',
                    radio: 'blaupunkt'
                }
            },
            {
                cc:2600, name: 'Killer', brand: 'Plymouth',
                interior: {
                    wheel: 'wooden',
                    radio: 'earache!'
                }
            },
        ]
    });


    现在是2019年,我们有2019年的方法来解决这个问题。)

    1
    Object.fromEntries(Object.entries({b: 3, a:8, c:1}).sort())


    如前所述,对象是无序的。

    然而。。。

    你可能会发现这个成语很有用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var o = { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' };

    var kv = [];

    for (var k in o) {
      kv.push([k, o[k]]);
    }

    kv.sort()

    然后,你可以通过kv迭代,做你想做的任何事情。

    1
    2
    3
    4
    > kv.sort()
    [ [ 'a', 'dsfdsfsdf' ],
      [ 'b', 'asdsad' ],
      [ 'c', 'masdas' ] ]


    下面是一个干净的基于lodash的版本,可以处理嵌套对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /**
     * Sort of the keys of an object alphabetically
     */

    const sortKeys = function(obj) {
      if(_.isArray(obj)) {
        return obj.map(sortKeys);
      }
      if(_.isObject(obj)) {
        return _.fromPairs(_.keys(obj).sort().map(key => [key, sortKeys(obj[key])]));
      }
      return obj;
    };

    如果罗达什采用toObject()方法,则更清洁。


    只需使用lodash解压映射并按pair和zip的第一个值排序,它将返回排序的键。

    如果希望sortby值,请将pair索引更改为1而不是0

    1
    2
    var o = { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' };
    console.log(_(o).toPairs().sortBy(0).fromPairs().value())

    enter image description here


    简单易读的代码片段,使用lodash。

    只有在调用sortby时,才需要将密钥放在引号中。它不必在数据本身中加引号。

    1
    _.sortBy(myObj,"key")

    另外,映射的第二个参数是错误的。它应该是一种功能,但使用拔毛更容易。

    1
    _.map( _.sortBy(myObj,"key") ,"value");

    解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function getSortedObject(object) {
      var sortedObject = {};

      var keys = Object.keys(object);
      keys.sort();

      for (var i = 0, size = keys.length; i < size; i++) {
        key = keys[i];
        value = object[key];
        sortedObject[key] = value;
      }

      return sortedObject;
    }

    // Test run
    getSortedObject({d: 4, a: 1, b: 2, c: 3});

    说明:

    许多JavaScript运行时按照添加的顺序将值存储在对象内。

    要按对象的键对其属性排序,可以使用object.keys函数,该函数将返回键数组。然后可以通过array.prototype.sort()方法对键数组进行排序,该方法对数组元素进行就地排序(无需将它们赋给新变量)。

    排序完键后,可以开始逐个使用它们来访问旧对象的内容,以填充新对象(现在已排序)。

    下面是该过程的一个示例(您可以在目标浏览器中对其进行测试):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    /**
     * Returns a copy of an object, which is ordered by the keys of the original object.
     *
     * @param {Object} object - The original object.
     * @returns {Object} Copy of the original object sorted by keys.
     */

    function getSortedObject(object) {
      // New object which will be returned with sorted keys
      var sortedObject = {};

      // Get array of keys from the old/current object
      var keys = Object.keys(object);
      // Sort keys (in place)
      keys.sort();

      // Use sorted keys to copy values from old object to the new one
      for (var i = 0, size = keys.length; i < size; i++) {
        key = keys[i];
        value = object[key];
        sortedObject[key] = value;
      }

      // Return the new object
      return sortedObject;
    }

    /**
     * Test run
     */

    var unsortedObject = {
      d: 4,
      a: 1,
      b: 2,
      c: 3
    };

    var sortedObject = getSortedObject(unsortedObject);

    for (var key in sortedObject) {
      var text ="Key:" + key +", Value:" + sortedObject[key];
      var paragraph = document.createElement('p');
      paragraph.textContent = text;
      document.body.appendChild(paragraph);
    }

    注意:object.keys是一个ecmascript 5.1方法,但这里有一个旧浏览器的polyfill:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if (!Object.keys) {
      Object.keys = function (object) {
        var key = [];
        var property = undefined;
        for (property in object) {
          if (Object.prototype.hasOwnProperty.call(object, property)) {
            key.push(property);
          }
        }
        return key;
      };
    }


    @sindresorhus有一个很棒的项目,叫做排序键,非常有用。

    您可以在此处检查其源代码:

    https://github.com/sindresorhus/sort-keys

    或者您可以将其与NPM一起使用:

    1
    $ npm install --save sort-keys

    以下是他的自述中的代码示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    const sortKeys = require('sort-keys');

    sortKeys({c: 0, a: 0, b: 0});
    //=> {a: 0, b: 0, c: 0}

    sortKeys({b: {b: 0, a: 0}, a: 0}, {deep: true});
    //=> {a: 0, b: {a: 0, b: 0}}

    sortKeys({c: 0, a: 0, b: 0}, {
        compare: (a, b) => -a.localeCompare(b)
    });
    //=> {c: 0, b: 0, a: 0}

    如果有嵌套对象或有嵌套数组对象,请使用此代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    var sortObjectByKey = function(obj){
        var keys = [];
        var sorted_obj = {};
        for(var key in obj){
            if(obj.hasOwnProperty(key)){
                keys.push(key);
            }
        }
        // sort keys
        keys.sort();

        // create new array based on Sorted Keys
        jQuery.each(keys, function(i, key){
            var val = obj[key];
            if(val instanceof Array){
                //do for loop;
                var arr = [];
                jQuery.each(val,function(){
                    arr.push(sortObjectByKey(this));
                });
                val = arr;

            }else if(val instanceof Object){
                val = sortObjectByKey(val)
            }
            sorted_obj[key] = val;
        });
        return sorted_obj;
    };


    在保留引用的同时对键进行递归排序。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function sortKeys(o){
        if(o && o.constructor === Array)
            o.forEach(i=>sortKeys(i));
        else if(o && o.constructor === Object)
            Object.entries(o).sort((a,b)=>a[0]>b[0]?1:-1).forEach(e=>{
                sortKeys(e[1]);
                delete o[e[0]];
                o[e[0]] = e[1];
            });
    }

    例子:

    1
    2
    3
    4
    5
    6
    7
    let x = {d:3, c:{g:20, a:[3,2,{s:200, a:100}]}, a:1};
    let y = x.c;
    let z = x.c.a[2];
    sortKeys(x);
    console.log(x); // {a: 1, c: {a: [3, 2, {a: 1, s: 2}], g: 2}, d: 3}
    console.log(y); // {a: [3, 2, {a: 100, s: 200}}, g: 20}
    console.log(z); // {a: 100, s: 200}


    我将一些Java枚举转移到JavaScript对象。

    这些对象为我返回了正确的数组。如果对象键是混合类型(string、int、char),则存在问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    var Helper = {
        isEmpty: function (obj) {
            return !obj || obj === null || obj === undefined || Array.isArray(obj) && obj.length === 0;
        },

        isObject: function (obj) {
            return (typeof obj === 'object');
        },

        sortObjectKeys: function (object) {
            return Object.keys(object)
                .sort(function (a, b) {
                    c = a - b;
                    return c
                });
        },
        containsItem: function (arr, item) {
            if (arr && Array.isArray(arr)) {
                return arr.indexOf(item) > -1;
            } else {
                return arr === item;
            }
        },

        pushArray: function (arr1, arr2) {
            if (arr1 && arr2 && Array.isArray(arr1)) {
                arr1.push.apply(arr1, Array.isArray(arr2) ? arr2 : [arr2]);
            }
        }
    };

    function TypeHelper() {
        var _types = arguments[0],
            _defTypeIndex = 0,
            _currentType,
            _value;

        if (arguments.length == 2) {
            _defTypeIndex = arguments[1];
        }

        Object.defineProperties(this, {
            Key: {
                get: function () {
                    return _currentType;
                },
                set: function (val) {
                    _currentType.setType(val, true);
                },
                enumerable: true
            },
            Value: {
                get: function () {
                    return _types[_currentType];
                },
                set: function (val) {
                    _value.setType(val, false);
                },
                enumerable: true
            }
        });

        this.getAsList = function (keys) {
            var list = [];
            Helper.sortObjectKeys(_types).forEach(function (key, idx, array) {
                if (key && _types[key]) {

                    if (!Helper.isEmpty(keys) && Helper.containsItem(keys, key) || Helper.isEmpty(keys)) {
                        var json = {};
                        json.Key = key;
                        json.Value = _types[key];
                        Helper.pushArray(list, json);
                    }
                }
            });
            return list;
        };

        this.setType = function (value, isKey) {
            if (!Helper.isEmpty(value)) {
                Object.keys(_types).forEach(function (key, idx, array) {
                    if (Helper.isObject(value)) {
                        if (value && value.Key == key) {
                            _currentType = key;
                        }
                    } else if (isKey) {
                        if (value && value.toString() == key.toString()) {
                            _currentType = key;
                        }
                    } else if (value && value.toString() == _types[key]) {
                        _currentType = key;
                    }
                });
            } else {
                this.setDefaultType();
            }
            return isKey ? _types[_currentType] : _currentType;
        };

        this.setTypeByIndex = function (index) {
            var keys = Helper.sortObjectKeys(_types);
            for (var i = 0; i < keys.length; i++) {
                if (index === i) {
                    _currentType = keys[index];
                    break;
                }
            }
        };

        this.setDefaultType = function () {
            this.setTypeByIndex(_defTypeIndex);
        };

        this.setDefaultType();
    }


    var TypeA = {
       "-1":"Any",
       "2":"2L",
       "100":"100L",
       "200":"200L",
       "1000":"1000L"
    };

    var TypeB = {
       "U":"Any",
       "W":"1L",
       "V":"2L",
       "A":"100L",
       "Z":"200L",
       "K":"1000L"
    };
    console.log('keys of TypeA', Helper.sortObjectKeys(TypeA));//keys of TypeA ["-1","2","100","200","1000"]

    console.log('keys of TypeB', Helper.sortObjectKeys(TypeB));//keys of TypeB ["U","W","V","A","Z","K"]

    var objectTypeA = new TypeHelper(TypeA),
        objectTypeB = new TypeHelper(TypeB);

    console.log('list of objectA = ', objectTypeA.getAsList());
    console.log('list of objectB = ', objectTypeB.getAsList());

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Types:

    var TypeA = {
       "-1":"Any",
       "2":"2L",
       "100":"100L",
       "200":"200L",
       "1000":"1000L"
    };

    var TypeB = {
       "U":"Any",
       "W":"1L",
       "V":"2L",
       "A":"100L",
       "Z":"200L",
       "K":"1000L"
    };


    Sorted Keys(output):

    Key list of TypeA -> ["-1","2","100","200","1000"]

    Key list of TypeB -> ["U","W","V","A","Z","K"]

    纯javascript应答来排序对象。这是我所知道的唯一能处理负数的答案。此函数用于对数字对象进行排序。

    输入obj=1000:,-1200:,10000:,200:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    function osort(obj) {
    var keys = Object.keys(obj);
    var len = keys.length;
    var rObj = [];
    var rK = [];
    var t = Object.keys(obj).length;
    while(t > rK.length) {
        var l = null;
        for(var x in keys) {
            if(l && parseInt(keys[x]) < parseInt(l)) {
                l = keys[x];
                k = x;
            }
            if(!l) { // Find Lowest
                var l = keys[x];
                var k = x;
            }
        }
        delete keys[k];
        rK.push(l);
    }

    for (var i = 0; i < len; i++) {

        k = rK[i];
        rObj.push(obj[k]);
    }
    return rObj;
    }

    输出将是一个按这些数字排序的对象,新键从0开始。


    简单点,让马特·鲍尔的回答更清楚。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //your object
    var myObj = {
        b : 'asdsadfd',
        c : 'masdasaf',
        a : 'dsfdsfsdf'
      };

    //fixed code
    var keys = [];
    for (var k in myObj) {
      if (myObj.hasOwnProperty(k)) {
        keys.push(k);
      }
    }
    keys.sort();
    for (var i = 0; i < keys.length; i++) {
      k = keys[i];
      alert(k + ':' + myObj[k]);
    }


    不确定这是否回答了问题,但这正是我需要的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Maps.iterate.sorted = function (o, callback) {
        var keys = Object.keys(o), sorted = keys.sort(), k;
        if ( callback ) {
                var i = -1;
                while( ++i < sorted.length ) {
                        callback(k = sorted[i], o[k] );
                }
        }

        return sorted;
    }

    称为:

    1
    Maps.iterate.sorted({c:1, b:2, a:100}, function(k, v) { ... } )