키를 기준으로 JavaScript 객체 정렬


532

JavaScript 객체를 키별로 정렬해야합니다.

따라서 다음과 같습니다.

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

될 것입니다 :

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


39
ECMAScript 사양에 따르면 2011 년 (이 질문이 게시 된 시점)에 JavaScript 객체는 고유 한 순서가 없다고합니다. 관찰 된 순서는 구현에 따라 다르므로 신뢰할 수 없었습니다. 그러나 모든 JavaScript 엔진이 거의 동일한 의미를 구현했기 때문에 이제 ES6에서 표준화되었습니다 . 결과적으로 아래의 많은 답변이 사양에 따라 정확했지만 이제는 정확하지 않습니다.
Mathias Bynens 2016 년


객체가 단지지도이거나 언어에 따라 좌우되는 것을 고려할 때, 왜 그렇게 할 이유가 거의 없습니다. 주의 사항 : 일반적으로 맵에 삽입되는 순서는 사실 스트링화할 때의 순서입니다. 따라서 새로운 맵을 만들고 미리 정렬 된 키 목록을 기반으로 값을 할당하면 키를 기반으로 정렬 된 맵을 찾을 수 있습니다.
Fallenreaper

그 이후주의 Object.entriesObject.fromEntriesJS에 첨가하고,이 멋지게 짧은 한 줄을 달성 할 수 있습니다 :Object.fromEntries(Object.entries(obj).sort())
마이크 'POMAX'Kamermans

답변:


471

이 질문에 대한 다른 답변은 구식이며 구현 현실과 결코 일치하지 않으며 ES6 / ES2015 사양이 게시되어 공식적 으로 잘못되었습니다.


참조 섹션 속성 반복 순서ES6 탐색 악셀 Rauschmayer에 의해 :

속성 키를 반복하는 모든 메서드는 동일한 순서로 수행됩니다.

  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().forEach(function(key) {
  ordered[key] = unordered[key];
});

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

ES5 엔진과의 호환성 var대신에 사용하십시오 const.


5
약간 다른 루핑 기술을 사용하는 것 외에는 코드와 최고의 대답의 차이를 실제로 볼 수 없습니다. 객체가 "순서대로"말할 수 있는지 여부는 관련이없는 것 같습니다. 이 질문에 대한 답은 여전히 ​​같습니다. 게시 된 사양은 여기에 대한 답변 만 확인합니다.
Phil

6
참고로, 속성 의 열거 순서는 아직 정의되지 않았습니다. esdiscuss.org/topic/…
Felix Kling

6
@ Phil_1984_이 답변과 가장 많이 투표 된 답변은 매우 다릅니다. OP의 질문은 객체 리터럴을 정렬하는 방법이었습니다. 최고 투표 답변에 따르면 정렬 할 수없는 키를 배열에 저장 한 다음 정렬 된 배열에서 키 값 쌍을 반복하고 인쇄하여 해결 방법을 제공합니다. 이 답변은 객체 리터럴의 순서가 이제 정렬 가능하고 그의 예제는 정렬 된 키 값을 객체 리터럴에 다시 저장 한 다음 정렬 된 객체를 직접 인쇄한다고 주장합니다. 참고로, 연결된 사이트가 여전히 존재하면 좋을 것입니다.
cchamberlain

6
두 답변 모두 Array.sort 함수를 사용하여 키를 먼저 정렬합니다. OP는 "JavaScript 개체"를 정렬하도록 요청하고 있으며 2 개의 개체를 설명하기 위해 JSON (JavaScript Object Notation) 만 사용합니다. 이 두 개체는 논리적으로 동일하므로 정렬이 관련이 없습니다. 가장 좋은 대답은 이것을 훨씬 잘 설명한다고 생각합니다. "다른 모든 답변이 공식적으로 잘못되었습니다"라고 말하는 것은 나에게 너무 극단적이며, 특히 링크가 끊어졌습니다. 문제는 "이 새로운 ES6 사양"이 Javascript 객체에 순서가 맞지 않은 키 목록을 가지고 있다는 착각을주고 있다고 생각합니다.
Phil

1
이 솔루션은 다양한 최신 브라우저 (Google "caniuse ES6")에서 지원되지 않습니다. 이 답변을 사용하면 특정 브라우저에서만 찾기 어려운 버그가 발생할 위험이 있습니다 (예 : Chrome이 모두 괜찮은 경우 Safari).
Manuel Arwed Schmidt

244

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 pedantic하지는 않지만 JSON 객체와 같은 것은 없습니다 .


2
@MarcelKorpel JSON 객체와 같은 것이 있습니다. 공식 JSON RFC 섹션 8을 확인하십시오. ietf.org/rfc/rfc4627.txt
Paul

8
@Paulpro는 RFC에 대해 두 가지주의 할 점이있다. 첫째,이 시점에서 7 살이고 시간이 지남에 따라 어휘가 바뀐다. 둘째, "이 메모는 인터넷 커뮤니티를위한 정보를 제공합니다. 어떤 종류의 인터넷 표준도 명시하지 않았습니다." 주어진 문자 시퀀스가 ​​JavaScript 객체 리터럴 또는 JSON 텍스트를 나타내는 지 여부는 컨텍스트 / 사용에 따라 다릅니다. "JSON 객체"라는 용어는 구분을 해치 며 모호하게 만듭니다. 부정확 한 용어를 제거하고 가능한 경우보다 정확한 용어를 사용하십시오. 달리 할 이유가 없습니다. 말이 중요합니다.
매트 볼

6
@MattBall IMO JSON 객체는 {"a", 1}JSON 배열 과 같은 문자열에 대한 정확한 용어와 같이 문자열에 대한 매우 정확한 용어입니다 [1]. 문자열이있을 때 배열의 세 번째 객체와 같은 것을 말함으로써 통신 할 수 있으므로 유용합니다 [{x: 1}, {y: 2}, {z: 3}]. 그래서 Javascript 리터럴에 대해 주석을 달 때 "JSON 객체가 아닙니다"를 선호합니다. OP가 실제로 JSON과 함께 작동 할 때 나중에 더 혼란과 의사 소통이 발생할 수 있습니다.
Paul

3
@Paulpro 동의하지 않습니다. {"a", 1}객체 리터럴 또는 JSON 텍스트입니다 (실제로 원하는 경우 JSON 문자열). 컨텍스트에 따라 달라지며, 전자는 JavaScript 소스 코드 내에서 그대로 표시되면 후자는 JSON 파서로 전달되어 추가로 사용되어야하는 문자열 인 경우에 영향을받습니다. 허용되는 구문, 올바른 사용법 및 직렬화와 관련하여 둘 사이에는 실제 차이점이 있습니다.
매트 볼

4
ES6 / ES2015가 완성되었으므로이 답변은 공식적으로 잘못되었습니다. 자세한 내용은 내 답변을 참조하십시오.
Mathias Bynens 2016 년

172

많은 사람들이 "객체를 정렬 할 수 없다"고 언급 했지만 그 후에는 작동하는 솔루션을 제공합니다. 역설, 그렇지 않습니까?

왜 이러한 솔루션이 작동하는지 언급하지 않습니다. 대부분의 브라우저 구현에서 객체의 값이 추가 된 순서대로 저장되기 때문입니다. 그래서 정렬 된 키 목록에서 새 객체를 만들면 예상 결과가 반환됩니다.

그리고 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제공된 객체 ( obj또는 o) 의 키 목록을 제공 한 다음 기본 정렬 알고리즘을 .reduce사용하여 키를 정렬합니다. 다음 으로 해당 배열을 다시 객체로 변환하는 데 사용되지만 이번에는 모든 키가 정렬됩니다.


7
@Pointy이 동작은 모든 주요 브라우저에서 항상 사용할 수 있으며 ES6 / ES2015에서 표준화되었습니다 . 나는 이것이 좋은 조언이라고 말하고 싶다.
Mathias Bynens 2016 년

3
이것은 EcmaScript v5에서 가장 간단하고 간결한 작업 수행 방법입니다. 파티에 조금 늦었지만 받아 들여지는 대답이어야합니다.
Steven de Salas

2
"그들은 대부분의 브라우저 구현에서 객체의 값이 추가 된 순서대로 저장되기 때문에" 숫자가 아닌 속성에만 해당됩니다. 또한 속성이 반복되는 순서 (예 :를 통해 for...in) 는 여전히 보장되지 않습니다 .
Felix Kling

2
그것이 왜 효과가 있는지 설명 해주셔서 감사합니다. 감사!
ola

5
내 린 터는 그 한 줄짜리 (과제를 반환)에 대해 불평했지만 이것은 나에게 효과적이며 읽기가 더 쉽습니다.Object.keys(dict).sort().reduce((r, k) => Object.assign(r, { [k]: dict[k] }), {});
aks.

68

얘들 아 나는 비 유적으로 충격을 받았습니다! 모든 대답이 다소 오래되었지만 정렬의 안정성에 대해서는 아무도 언급하지 않았습니다! 저와 함께 견딜 수 있도록 최선을 다해 질문에 답변하고 여기에 자세히 설명하겠습니다. 이제 사과하겠습니다. 읽을 거리가 많습니다.

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

누군가 감소가 궁금한 경우 :

// 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 () 메서드는 배열의 요소를 적절하게 정렬하고 배열을 반환합니다. 정렬이 반드시 안정적인 것은 아닙니다. 기본 정렬 순서는 문자열 유니 코드 코드 포인트에 따릅니다.

정렬의 시간 및 공간 복잡성은 구현에 따라 다르므로 보장 할 수 없습니다.

그들 중 하나가 원하는 결과를 반환하는지 확인해야합니다. 실제 예제에서 사람들은 API 및 데이터베이스와 같은 서로 다른 정보 입력을 함께 사용하는 경우 상황을 정리하는 경향이 있습니다.


그래서 큰 문제는 무엇입니까?

모든 프로그래머가 이해해야 할 두 가지 기사가 있습니다.

내부 알고리즘 :

컴퓨터 과학에서 인플레 이스 알고리즘은 보조 데이터 구조를 사용하지 않고 입력을 변환하는 알고리즘입니다. 그러나 보조 변수에는 소량의 추가 저장 공간이 허용됩니다. 알고리즘이 실행될 때 일반적으로 입력이 출력에 의해 덮어 쓰기됩니다. 인플레 이스 알고리즘은 요소 교체 또는 교체를 통해서만 입력 시퀀스를 업데이트합니다. 제자리에 있지 않은 알고리즘을 제자리 안 또는 제자리라고도합니다.

기본적으로 기존 배열을 덮어 씁니다! 다른 이유로 기존 어레이를 유지하려는 경우에 중요합니다. 따라서 이것을 명심하십시오.

정렬 알고리즘

안정적인 정렬 알고리즘은 입력에 나타나는 것과 동일한 순서로 동일한 요소를 정렬합니다. 일부 종류의 데이터를 정렬 할 때는 정렬 순서를 결정할 때 데이터의 일부만 검사합니다. 예를 들어, 오른쪽에있는 카드 정렬 예에서 카드는 순위별로 정렬되며 해당 수트는 무시됩니다. 이를 통해 원래 목록의 여러 가지 올바르게 정렬 된 버전을 사용할 수 있습니다. 안정적인 정렬 알고리즘은 다음 규칙에 따라 다음 중 하나를 선택합니다. 두 개의 5 카드와 같이 두 항목이 동일하게 비교되는 경우 상대 순서가 유지되므로 입력에서 다른 항목보다 먼저 오면 출력에서 다른 것보다 먼저 나옵니다.

여기에 이미지 설명을 입력하십시오

카드 놀이에서 안정적인 종류의 예. 카드가 안정적인 정렬로 순위별로 정렬 될 때 두 5는 원래 있던 정렬 된 출력에서 ​​동일한 순서로 유지되어야합니다. 불안정한 정렬로 정렬 된 경우 5는 반대 방향으로 끝날 수 있습니다. 정렬 된 출력에서 ​​순서.

이것은 정렬이 옳지 만 변경되었음을 나타냅니다. 따라서 현실 세계에서 정렬이 정확하더라도 우리가 기대하는 것을 얻도록해야합니다! 이것도 명심하십시오. 더 많은 JavaScript 예제는 Array.prototype.sort ()-docs를 참조하십시오 . https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort


3
당신은 바위를 뒤집어 놓습니다.이 놀라운 대답에 감사드립니다. 내가 본 것 중에 최고 중 하나. 건배.
Gavin

마지막에 사용할 수있는 괴물 방법을 제공 할 수 있다면. 그래도 좋은 답변입니다!
mmm

@ momomo 문제는 정렬에서 기대하는 것에 따라 올바른 방법이 없다는 것입니다. 그러나 내 대답 에서이 코드를 간단하게 사용할 수 있습니다 Object.keys(testObj).sort().reduce((a, c) => (a[c] = testObj[c], a), {}).
Megajin

정렬의 안정성이이 질문에 해당되지 않습니다 : 우리는 객체 키를 기준으로 정렬하고 있으며 키는 고유합니다. (예를 들어 카드를 확장하기 위해 : 다른 옷을 입고 있어도 팩에 두 개의 5가있을 수는 없습니다.)
Darren Cook

@DarrenCook 좋은 질문입니다! 하나의 객체에 동일한 키가 없을 것입니다. 그러나 안정성은 키의 고유성보다 더 복잡합니다. 대부분의 경우 배열은 개체 정렬에 포함됩니다. 그리고 모든 것이 불안정해질 수 있습니다. 5 명의 플레이어가있는 카드 게임을 상상해보십시오. 각 핸드는 배열 (개별 핸드 정렬을 유지하기 위해)과 카드를 개체로 나타냅니다. 카드가 이와 같 {5: 'hearts'}거나 {5: 'spades'}배열 정렬을 시작하면 더미 같은 게임에서 잠재적으로 불안정해질 수 있습니다. 다른 언어를 말할 수 없습니다.
Megajin

29

이것은 나를 위해 작동

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

10
이것은 실제로 질문에 대한 정답입니다. Underscore를 사용하는 단순화 된 버전은 다음을 참조하십시오. jsfiddle.net/wPjaQ/1
radicand

6
@radicand이 답변은 정확하지 않습니다. 순서가없는 새 객체를 반환합니다.
Paul

3
@radicand 그것은 실제로도 아니다. 객체 키에는 순서와 같은 것이 없으므로 실제로 객체가 정렬 된 순서로 객체를 제공한다고 어떻게 말할 수 있습니까? 실제로 전달한 객체의 얕은 복사본을 다시 제공합니다.
Paul

9
이것은 매우 잘못입니다. 지금은 작동하지만 다른 웹 브라우저에서 또는 동일한 브라우저에서 다른 페이지로드가 중단 될 수 있습니다. 브라우저는 보안을 위해 객체 키를 무작위로 생성하거나 객체를 채울 때 키에 따라 다른 메모리 버킷에 값을 저장하여 다른 순서를 반환합니다. 이것이 효과가 있다면 운이 좋다.
Yobert

11
또한 jQuery를 불필요하게 사용합니다.
RobG

25

2019 년 이며이 문제를 해결하는 2019 방법이 있습니다 :)

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

2
중첩 된 객체를 키별로 어떻게 정렬합니까?
a2441918

@ a2441918 sort () 함수와 같은 방식으로. 보세요 : developer.mozilla.org/de/docs/Web/JavaScript/Reference/… Object.fromEntries (Object.entries ({b : 3, a : 8, c : 1}). sort ((k, j ) => k-j))
user2912903

TypeScript 사용자는 아직 사용할 수 없습니다. github.com/microsoft/TypeScript/issues/30933
tsujp

좋은 한 줄짜리지만 대소 문자를 구분하지 않고 키를 정렬하는 방법은 무엇입니까?
12

1
@theMaxx 정렬에 사용자 정의 함수를 사용하십시오.```Object.fromEntries (Object.entries ({b : 3, a : 8, c : 1}). sort (([[1, val1], [key2 val2]) => key1.toLowerCase (). localeCompare (key2.toLowerCase ())))```
Ben

22

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


이 미친 문법은 무엇입니까? (o[k] = v, o). 왜 이것이 작동합니까? 어떻게 문서를 찾을 수 있습니까? 분명히 가장 오른쪽의 매개 변수를 반환하지만 그 이유는 무엇입니까?
ntaso

1
@ntaso 여기에
James

짧은 함수는 먼저하게 o[k]일치 한 v다음 되돌아o
Tahsin Turkoz

19

이것은 오래된 질문이지만 Mathias Bynens의 답변에서 힌트를 얻었으므로 현재 객체를 많은 오버 헤드없이 정렬하기 위해 짧은 버전을 만들었습니다 .

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

코드 실행 후 "정렬되지 않은"객체 자체에는 키가 알파벳순으로 정렬됩니다.


17

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

그냥 생각할 음식.


15

정렬되지 않은 개체 속성을 표시하는 VisualStudio 디버거에서 유용 할 수 있다고 가정합니다.

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

정말 감사합니다 loooot
Mugiwara

좋은! 간결한 솔루션에 감사드립니다.
Con Antonakos

9

밑줄 버전 :

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

키의 순서를 유지한다고 브라우저를 신뢰하지 않는 경우 순서가 지정된 키-값 쌍 배열을 사용하는 것이 좋습니다.

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

더 나은 :_.object(_.sortBy(_.pairs(unordered), _.first))
Afanasii Kurakin

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

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

코드에 대한 설명을 추가하는 것이 좋습니다.
aristotll

1
객체의 키를 가져옵니다. 따라서 문자열 배열이므로 정렬합니다. 문자열 배열 (키)이므로 줄입니다 (js Array의 reduce () 사용). acc는 초기에 빈 객체 {} (리듀서의 마지막 인수)이고 리듀서 (콜백)는 빈 객체에 순서가 지정된 키 시퀀스를 가진 소스 obj의 값을 할당합니다.
user3286817

8

좀 더 우아한 형태 일 수도 있습니다.

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

아무것도 정렬되지 않습니다. 여전히 객체를 반환합니다. 대상의 오브젝트가 실제로 순서를 갖도록 보장 할 수 없습니다. 배열을 반환해야합니다. jeeezus.
mmm

여기서 당신이하는 유일한 일은 그것이 최적이 아닌 방식으로 설정되도록하는 것입니다.
mmm

7

중첩 객체 및 배열에 대한 재귀 정렬

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

나는 당신이 else거기에 필요하다고 생각합니다. Array.isArray(obj[key])그리고 둘 다에 해당 될 수 있습니다.typeof obj[key] === 'object'
jononomo

프리미티브 배열이 있으면 함수는 프리미티브 (문자열 / 숫자)를 빈 객체로 변환합니다. 이것을 잡기 위해 함수의 시작 부분에 다음을 추가했습니다. function sortObjectKeys(obj){: if(typeof obj != 'object'){ /* it is a primitive: number/string (in an array) */ return obj; }. 전체 시작시 견고성 I의 경우도 추가 :if(obj == null || obj == undefined){ return obj; }
isgoed

4

이미 언급했듯이 객체는 정렬되지 않습니다.

하나...

이 관용구가 유용 할 수 있습니다.

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


4

중첩 된 객체로 작동하는 깨끗한 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()방법 이 있다면 더 깨끗할 것입니다 ...


3

lodash를 사용하여 map의 압축을 풀고 sortBy의 첫 번째 값을 다시 압축하면 정렬 된 키가 반환됩니다.

sortby 값을 원하면 페어 인덱스를 0 대신 1로 변경하십시오.

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

여기에 이미지 설명을 입력하십시오


편집 링크를 사용 하여이 코드의 작동 방식을 설명하고 코드를 제공하지 마십시오. 설명은 향후 독자에게 도움이 될 것입니다. 답변 방법 도 참조하십시오 . 출처
Jed Fox

3

참조를 유지하면서 키를 재귀 적으로 정렬합니다.

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}

좋은 발췌 문장! delete o[e[0]];거기 의 목적은 무엇입니까 ? 우리는 단지 할당 할 수 있습니까?
Boyang

존재하지 않는 키에 대한 새로운 할당 만 끝에 키를 추가하는 것처럼 보입니다. 삭제가 주석 처리 된 경우 적어도 Chrome에서는 키가 정렬되지 않습니다.
brunettdan

말이 되네요 감사! 어쨌든, 사양에 따르면 js 객체 키에 시퀀스가 ​​없기 때문에 이것은 일종의 손실 원인입니다. 우리는 방금 obj 및 log 함수 impl 세부 정보를 이용하고 있습니다.
Boyang

예, 키 순서가 중요한 경우 맵을 사용합니다. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
brunettdan

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

3

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

2

중첩 된 객체가 있거나 중첩 된 배열 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;
};

5
저자는 그가 jQuery를 사용하고 있다고 말하지 않았으며 jQuery라는 태그를 붙인 질문도 없습니다. 순수한 자바 스크립트로 솔루션을 추가하면 좋을 것입니다.
rusmus

@Phani에게 감사합니다 이것은 내가 정확히 필요한 것입니다
Will Sheppard

2

해결책:

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 방법이지만 이전 브라우저를위한 폴리 필은 다음과 같습니다.

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

2

Java 열거 형을 자바 스크립트 객체로 옮겼습니다.

이 객체는 올바른 배열을 반환했습니다. 객체 키가 혼합 유형 (문자열, 정수, 문자)이면 문제가있는 것입니다.

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

2

lodash를 사용하는 간단하고 읽기 쉬운 스 니펫.

sortBy를 호출 할 때만 키를 따옴표로 묶어야합니다. 데이터 자체에서 따옴표로 묶을 필요는 없습니다.

_.sortBy(myObj, "key")

또한 두 번째로 매핑 할 매개 변수가 잘못되었습니다. 함수 여야하지만 퍽을 사용하는 것이 더 쉽습니다.

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

2

@sindresorhus의 훌륭한 프로젝트 인 sort-keys가 있습니다.

소스 코드를 확인할 수 있습니다 :

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

또는 npm과 함께 사용할 수 있습니다.

$ npm install --save sort-keys

readme의 코드 예제도 있습니다.

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

객체를 정렬하는 순수 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부터 시작하는 새 키가있는 숫자로 정렬 된 객체입니다.


1

간단히 말하고 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]);
}


1

이것이 질문에 대한 대답인지 확실하지 않지만 이것이 내가 필요한 것입니다.

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

1

한 줄 :

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

1

가장 좋은 방법은

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

첫 번째 색인이 0 대신 1이므로 원인이 발생하면 끝에 빈 슬롯이 있습니다. .length-- 또는 .pop ()을 사용하여 빈 슬롯을 제거 할 수 있습니다.

또는 .reverse를 빌려서 같은 객체에서 호출하려면 완전히 배열 된 객체 여야합니다. 즉, 길이 속성이 필요합니다.

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

동일한 배열과 동일한 객체 객체를 반환하므로 실제 배열이 아닙니다. 그런 다음 delete를 사용하여 길이 속성을 제거 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.