繁体   English   中英

按键排序 JavaScript object

[英]Sort JavaScript object by key

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

因此如下:

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

会成为:

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

这个问题的其他答案已经过时,与实现现实不匹配,并且在 ES6 / ES2015 规范发布后正式变得不正确。


请参阅Axel Rauschmayer 的Exploring ES6中关于属性迭代顺序的部分

遍历属性键的所有方法都以相同的顺序进行:

  1. 首先是所有数组索引,按数字排序。
  2. 然后是所有字符串键(不是索引),按照它们的创建顺序。
  3. 然后是所有符号,按照它们的创建顺序。

所以是的,JavaScript 对象实际上是有序的,并且它们的键/属性的顺序是可以改变的。

以下是按字母顺序按键/属性对对象进行排序的方法:

 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().reduce( (obj, key) => { obj[key] = unordered[key]; return obj; }, {} ); console.log(JSON.stringify(ordered)); // → '{"a":"baz","b":"foo","c":"bar"}'

使用var而不是const以与 ES5 引擎兼容。

JavaScript 对象1没有排序。 试图对它们进行“排序”是没有意义的。 如果要遍历对象的属性,可以对键进行排序,然后检索关联的值:

 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的替代实现:

 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 函数式方式:

function sortObject(obj) {
    return Object.keys(obj).sort().reduce(function (result, key) {
        result[key] = obj[key];
        return result;
    }, {});
}

上面的 ES2015 版本(格式化为“单线”):

const sortObject = o => Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {})

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

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

伙计们,我形象地震惊了! 当然所有的答案都有些老了,但没有人提到排序的稳定性! 所以请耐心等待,我会尽力回答问题本身并在此处详细介绍。 所以我要道歉,现在阅读量会很大。

由于是 2018 年,我将只使用 ES6,所有 Polyfill 都可以在 MDN 文档中找到,我将在给定部分链接。


回答问题:

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

// 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()链接到所有这些中:

// 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), {}));

如果有人想知道 reduce 的作用:

// 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().
}, {});

如果需要,这里是对一个班轮的解释:

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.
  ,{}
);

为什么排序有点复杂:

简而言之, Object.keys()将返回一个与我们在正常循环中得到的顺序相同的数组:

const object1 = {
  a: 'somestring',
  b: 42,
  c: false
};

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

Object.keys() 返回一个数组,其元素是与直接在对象上找到的可枚举属性相对应的字符串。 属性的顺序与通过手动循环对象的属性给出的顺序相同。

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

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

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

这是一个示例,所有这些都在一个对象中:

// 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() ,输出会发生变化:

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

这是来自文档的引用:

sort() 方法对数组的元素进行就地排序并返回该数组。 排序不一定是稳定的。 默认排序顺序是根据字符串 Unicode 代码点。

无法保证排序的时间和空间复杂度,因为它取决于实现。

您必须确保其中一个为您返回所需的输出。 在现实生活中的示例中,如果您同时使用不同的信息输入(如 API 和数据库),人们往往会特别混淆事物。


那么有什么大不了的呢?

那么有两篇文章是每个程序员都应该了解的:

就地算法

在计算机科学中,就地算法是一种不使用辅助数据结构来转换输入的算法。 然而,辅助变量允许有少量的额外存储空间。 当算法执行时,输入通常被输出覆盖。 就地算法仅通过替换或交换元素来更新输入序列。 不就地的算法有时称为不就地或不就地。

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

排序算法

稳定的排序算法按照它们在输入中出现的相同顺序对相同的元素进行排序。 在对某些类型的数据进行排序时,在确定排序顺序时只检查部分数据。 例如,在右侧的卡片排序示例中,卡片按其等级排序,而它们的花色被忽略。 这允许原始列表的多个不同的正确排序版本的可能性。 稳定排序算法根据以下规则选择其中之一:如果两个项目比较相等,例如两张 5 卡,那么它们的相对顺序将被保留,因此如果输入中一个在另一个之前,它也会在输出中排在另一个之前。

在此处输入图像描述

扑克牌稳定排序的一个例子。 当卡片以稳定排序按等级排序时,两个 5 在它们原来所在的排序输出中必须保持相同的顺序。当它们以非稳定排序排序时,5 可能以相反的顺序结束排序输出中的顺序。

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

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

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

ES6 - 这是 1 班轮

 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), {} ));

这对我有用

/**
 * 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;
};

这是一个老问题,但从 Mathias Bynens 的回答中得到启发,我制作了一个简短版本来对当前对象进行排序,没有太多开销。

    Object.keys(unordered).sort().forEach(function(key) {
        var value = unordered[key];
        delete unordered[key];
        unordered[key] = value;
    });

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

使用 lodash 这将起作用:

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();

只是思考的食物。

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

(function(s) {
    var t = {};

    Object.keys(s).sort().forEach(function(k) {
        t[k] = s[k]
    });

    return t
})({
    b: 2,
    a: 1,
    c: 3
});

与内联版本相同:

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

实际上,我很惊讶给出了 30 多个答案,但没有一个为这个问题提供完整的深度解决方案。 有些解决方案很浅,而另一些解决方案很深但有问题(如果未定义,函数或符号将在 json 中,它将崩溃)。

这是完整的解决方案:

function sortObject(unordered, sortArrays = false) {
  if (!unordered || typeof unordered !== 'object') {
    return unordered;
  }

  if (Array.isArray(unordered)) {
    const newArr = unordered.map((item) => sortObject(item, sortArrays));
    if (sortArrays) {
      newArr.sort();
    }
    return newArr;
  }

  const ordered = {};
  Object.keys(unordered)
    .sort()
    .forEach((key) => {
      ordered[key] = sortObject(unordered[key], sortArrays);
    });
  return ordered;
}

const json = {
  b: 5,
  a: [2, 1],
  d: {
    b: undefined,
    a: null,
    c: false,
    d: true,
    g: '1',
    f: [],
    h: {},
    i: 1n,
    j: () => {},
    k: Symbol('a')
  },
  c: [
    {
      b: 1,
      a: 1
    }
  ]
};
console.log(sortObject(json, true));

下划线版本

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

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

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

也许更优雅的形式:

 /** * 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 }));

PS 和 ES6+ 语法相同:

function ksort( src ) {
  const keys = Object.keys( src );
  keys.sort();
  return keys.reduce(( target, key ) => {
        target[ key ] = src[ key ];
        return target;
  }, {});
};
function sortObjectKeys(obj){
    return Object.keys(obj).sort().reduce((acc,key)=>{
        acc[key]=obj[key];
        return acc;
    },{});
}

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

这是一个单行解决方案(不是最有效的,但是当涉及到像您的示例中那样的瘦对象时,我宁愿使用本机 JS 函数,然后搞乱草率的循环)

 const unordered = { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' } const ordered = Object.fromEntries(Object.entries(unordered).sort()) console.log(ordered); // a->b->c

// if keys are char/string
const sortObject = (obj) => Object.fromEntries(Object.entries(obj).sort( ));
let obj = { c: 3, a: 1 };
obj = sortObject(obj)

// if keys are numbers
const sortObject = (obj) => Object.fromEntries(Object.entries(obj).sort( (a,b)=>a-b ));
let obj = { 3: 'c', 1: 'a' };
obj = sortObject(obj)

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

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!'
            }
        },
    ]
});

这是一个基于 lodash 的干净版本,适用于嵌套对象

/**
 * 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;
};

如果 lodash 有一个toObject()方法会更干净......

Object.keys(unordered).sort().reduce(
    (acc,curr) => ({...acc, [curr]:unordered[curr]})
    , {}
)

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

然而...

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

var o = { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' };

var kv = [];

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

kv.sort()

然后,您可以遍历 kv 并做任何您想做的事情。

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

@sindresorhus 有一个很棒的项目,叫做 sort-keys,非常棒。

你可以在这里查看它的源代码:

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

或者你可以将它与 npm 一起使用:

$ npm install --save sort-keys

这也是他的自述文件中的代码示例

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}

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

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;
};

只需使用 lodash 解压缩 map 和 sortBy 对的第一个值并再次 zip 它将返回排序键。

如果您希望 sortby 值将对索引更改为1而不是0

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

在此处输入图像描述

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

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];
        });
}

例子:

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}

这是我对 JSON 排序所需的一切的轻量级解决方案。

function sortObj(obj) {
    if (typeof obj !== "object" || obj === null)
        return obj;

    if (Array.isArray(obj))
        return obj.map((e) => sortObj(e)).sort();

    return Object.keys(obj).sort().reduce((sorted, k) => {
        sorted[k] = sortObj(obj[k]);
        return sorted;
    }, {});
}

解决方案:

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()方法对键数组进行排序,该方法对数组的元素进行就地排序(无需将它们分配给新变量)。

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

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

 /** * 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:

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;
  };
}

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

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

 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());

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"]

一行:

Object.entries(unordered)
  .sort(([keyA], [keyB]) => keyA > keyB)
  .reduce((obj, [key,value]) => Object.assign(obj, {[key]: value}), {})

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

只有在调用 sortBy 时才需要将键放在引号中。 它不必在数据本身中用引号引起来。

_.sortBy(myObj, "key")

此外,您映射的第二个参数是错误的。 它应该是一个函数,但使用 pluck 更容易。

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

对对象进行排序的纯 JavaScript 答案。 这是我所知道的唯一可以处理负数的答案。 此功能用于对数字对象进行排序。

输入obj = {1000:{},-1200:{},10000:{},200:{}};

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 开始。

只是为了简化它并使 Matt Ball 的答案更清楚

 //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]); }

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

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;
}

称为:

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

最好的方法是

 const object =  Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {})

 //else if its in reverse just do 

 const object = Object.keys(0).reverse ()

您可以先将几乎类似数组的对象转换为真正的数组,然后使用 .reverse():

Object.assign([], {1:'banana', 2:'apple', 
3:'orange'}).reverse();
// [ "orange", "apple", "banana", <1 empty slot> ]

最后的空槽如果因为您的第一个索引是 1 而不是 0 而导致。您可以使用 .length-- 或 .pop() 删除空槽。

或者,如果你想借用 .reverse 并在同一个对象上调用它,它必须是一个完全类似数组的对象。 也就是说,它需要一个长度属性:

Array.prototype.reverse.call({1:'banana', 2:'apple', 
3:'orange', length:4});
// {0:"orange", 1:"apple", 3:"banana", length:4}

请注意,它将返回相同的完全类似数组的对象对象,因此它不是真正的数组。 然后,您可以使用 delete 删除长度属性。

我喜欢上面的这个 aswer,但它不起作用:

/**
 * 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;
};

看起来 sorted_obj 没有顺序保证,因为该地图似乎更合适,我最终更改了地图的对象,如下所示:

/**
 * Return an Object sorted by it's Key
 */
var sortObjectByKey = function(obj){
    var keys = [];
    let sorted_map = new Map();

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

    // sort keys
    keys.sort();

    // create new map based on Sorted Keys
    keys.forEach(key => {
        sorted_map.set(key, obj[key]);
    });

    return sorted_map;
};

 const sortObjectByKeys = (object) => Object.fromEntries( Object.entries(object).sort(([k1], [k2]) => k1 < k2 ? -1 : 1) ) const object = {b: 'asdsad', c: 'masdas', a: 'dsfdsfsdf' } const orderedObject = sortObjectByKeys(object) console.log(orderedObject)

当搜索如何在 Typescript 中对对象进行排序时也会出现这个问题,所以在这里添加对我有用的东西。

使用 typescript,我在使用reduce方法泛化类型时遇到了麻烦。 这就是我最终做的事情:

function sortObject<T>(obj: T, compareFn?: ((a: unknown, b: unknown) => number)) {
    let keys: unknown[];

    if (compareFn) {
        keys = Object.keys(obj).sort(compareFn);
    } else {
        keys = Object.keys(obj).sort();
    }

    // Storing the data in temp object and deleting from the original
    const temp = {} as typeof obj;

    for (let i = 0; i < keys.length; ++i) {
        const typedKey = keys[i] as keyof typeof obj;
        temp[typedKey] = obj[typedKey];
        delete obj[typedKey];
    }

    // Restore the data in sorted order back into the original object
    for (let i = 0; i < keys.length; ++i) {
        const typedKey = keys[i] as keyof typeof obj;
        obj[typedKey] = temp[typedKey];
    }

    return obj;
}

这从2023 年 1 月起有效

 var obj = { 'b':'cVal', 'a':'aVal', 'c':'bVal' } console.log(JSON.stringify(obj)) obj = Object.fromEntries(Object.entries(obj).sort()) console.log(JSON.stringify(obj));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM