Javascript에서 이름을 알파벳순으로 배열 정렬


645

JavaScript를 사용하여 이름별로 정렬 해야하는 배열 (배열의 한 객체에 대해서는 아래 참조)이 있습니다. 어떻게하니?

var user = {
   bio: null,
   email:  "user@domain.com",
   firstname: "Anna",
   id: 318,
   lastAvatar: null,
   lastMessage: null,
   lastname: "Nickson",
   nickname: "anny"
};

답변:


1065

배열이 있다고 가정합니다 users. users.sort두 개의 인수를 사용하여 비교하는 함수를 사용 하고 전달할 수 있습니다 (비교기)

돌아와야한다

  • 첫 번째 인수가 두 번째보다 작은 경우 음의 값 (결과 배열에서 두 번째 앞에 배치해야 함)
  • 첫 번째 인수가 클 경우 긍정적 인 것 (두 번째 인수 뒤에 놓아야 함)
  • 이 두 요소가 같으면 0입니다.

우리의 경우 두 요소가 a있고 b비교 a.firstname하고 싶습니다.b.firstname

예:

users.sort(function(a, b){
    if(a.firstname < b.firstname) { return -1; }
    if(a.firstname > b.firstname) { return 1; }
    return 0;
})

이 코드는 모든 유형에서 작동합니다.

"실제"™에서는 문자열을 비교할 때 대소 문자를 무시하고 분음 부호, ß와 같은 이상한 기호 등을 올바르게 정렬하기를 원하므로을 사용할 수 있습니다 localeCompare. 명확성을 위해 다른 답변을 참조하십시오.


5
Friggin 굉장 ... 나는 노드 목록을 ID별로 정렬하고 ... 매력처럼 작동합니다. Thx 톤!
Cody

74
나중에 오는 사람들에게는 대소 문자를 구분하지 않기 때문에 Mr.의 답변이 더 좋습니다.
mlienau

25
@ mlienau, 나는 그것을 더 나쁘게 부르지 않을 것입니다. 그것은 또 다른입니다
리야드

19
@RiaD 공정합니다. 'apple'이전에 'Zebra'가 목록에 나타나는 케이싱을 포함하여 알파벳순으로 항목을 정렬하는 많은 경우를 생각할 수는 없습니다.
mlienau

15
이 코드는 영어권 국가에서만 작동합니다. 다른 국가에서는 ovunccetin의 답변을로localeCompare 사용해야합니다 .
Spoike

543

ES6으로 가능한 가장 짧은 코드!

users.sort((a, b) => a.firstname.localeCompare(b.firstname))

String.prototype.localeCompare () 기본 지원은 보편적입니다!


27
2017 년에 살고 있다면 최고의 답변
nathanbirrell

52
2018 년에 거주하는 경우에도 가장 좋은 답변;)
Simone

49
아마도 2019 년에도 최고의 답변이 될 것입니다.
Ahmad

23
2020 년? 또는 naaa?
kspearrin

15
아, 2030 년에 지구는 홍수가 났고 이것은 산에서만 작동합니다.
Starfs

343

이 같은:

array.sort(function(a, b){
 var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase();
 if (nameA < nameB) //sort string ascending
  return -1;
 if (nameA > nameB)
  return 1;
 return 0; //default return value (no sorting)
});

43
문자열을 정렬 할 때 'toLowerCase ()'가 매우 중요합니다. 대문자는 정렬에 영향을 줄 수 있습니다.
MarzSocks

3
다른 사람이 toLowerCase가 어떤 영향을 미치는지 궁금해하는 경우별로 많지 않습니다.'a'>'A' //true 'z'>'a' //true 'A'>'z' //false
SimplGy

14
@SimplGy 나는 그 영향이 당신이 인정하는 것보다 조금 더 크다고 주장합니다. 예를 들어, 허용되는 답변에 대한 주석에 명시된 바와 같이 정렬 함수가 문자열 'Zebra'보다 문자열을 더 높은 정렬하는지 여부를 아는 것이 중요 'apple'합니다 .toLowerCase().
PrinceTyke

1
@PrinceTyke 그래, 좋은 사람이야. 'Z' < 'a' // true'z' < 'a' // false
SimplGy

2
모든 유효한 포인트와 정렬은 항상 "의존적"이라고 말하고 싶습니다. 이름별로 정렬하는 경우 대소 문자 구분이 중요하지 않을 수 있습니다. 다른 경우가 있습니다. 어쨌든 핵심 아이디어를 얻은 후에는 특정 상황에 적응하는 것이 어렵지 않다고 생각합니다.
Mr.

336

비교 된 문자열에 유니 코드 문자가 포함되어 있으면 다음과 같은 클래스 localeCompare기능 을 사용할 수 있습니다 String.

users.sort(function(a,b){
    return a.firstname.localeCompare(b.firstname);
})

3
String.localeCompare는 Safari 및 IE <11 :을 지원하지 않습니다.
CORSAIR

13
@CORSAIR 지원되지만 지원되지 않는 두 번째 및 세 번째 매개 변수입니다.
Codler

6
@CORSAIR 예제의 사용법은 모든 주요 IE 브라우저 ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) 에서 지원됩니다 . LocaleCompare도 대문자 사용을 고려하므로이 구현이 모범 사례로 간주되어야한다고 생각합니다.
매트 젠슨

9
users.sort ((a, b) => a.firstname.localeCompare (b.firstname)) // 짧은 n 스위트 ES6 버전!
Nachiketha

4
탱크 형제. ES6 사용users.sort((a, b) => a.name.localeCompare(b.name))
Mohmmad Ebrahimi Aval

32

멋진 작은 ES6 하나의 라이너 :

users.sort((a, b) => a.firstname !== b.firstname ? a.firstname < b.firstname ? -1 : 1 : 0);

2
이것은 동등한 값을 올바르게 처리하지 않기 때문에 불완전합니다.
Karl-Johan Sjögren

1
물론, 덕분에 그 얼룩을지게, 나는 일치하는 값에 대한 체크 추가 한
샘 로건

나쁘지 않다 나는 당신이 정말로 한 줄에 모든 것을 원한다면, 중첩 삼항은 가독성에 대해 혼란스러워 할 것이다
russter

24

localeCompare를 사용할 수 있지만 잘못된 값도 키를 확인해야합니다.

하나의 항목에 lname이 없으면 아래 코드가 작동하지 않습니다.

obj.sort((a, b) => a.lname.localeCompare(b.lname))

따라서 아래와 같이 잘못된 값을 확인해야합니다

let obj=[
{name:'john',lname:'doe',address:'Alaska'},
{name:'tom',lname:'hopes',address:'California'},
{name:'harry',address:'Texas'}
]
let field='lname';
console.log(obj.sort((a, b) => (a[field] || "").toString().localeCompare((b[field] || "").toString())));

또는

우리는 매우 간단한 lodash를 사용할 수 있습니다. 반환 된 값, 즉 숫자 또는 문자열을 감지하고 그에 따라 정렬합니다.

import sortBy from 'lodash/sortBy';
sortBy(obj,'name')

https://lodash.com/docs/4.17.5#sortBy


2
Lodash는 매우 깔끔합니다! 전에는 들어 본 적이 없습니다. 잘 작동합니다!
Derk Jan Speelman

15

underscorejs 는 매우 멋진 _.sortBy 함수를 제공합니다.

_.sortBy([{a:1},{a:3},{a:2}], "a")

또는 사용자 정의 정렬 기능을 사용할 수 있습니다.

_.sortBy([{a:"b"},{a:"c"},{a:"a"}], function(i) {return i.a.toLowerCase()})

2
두 번째 예는 문자열 반환과 관련이 있습니다. 않는다 sortBy반환 값이 문자열 때문에 알파벳 순으로 정렬이 수행 감지? 감사합니다
superjos

12

ñ 또는 áéíóú (스페인어 공용어) 와 같은 특수 문자로 이름이나 무언가를 정렬 하는 경우 params locales ( 이 경우 스페인어 es ) 및 다음과 같은 옵션을 사용할있습니다 .

let user = [{'firstname': 'Az'},{'firstname': 'Áb'},{'firstname':'ay'},{'firstname': 'Ña'},{'firstname': 'Nz'},{'firstname': 'ny'}];


user.sort((a, b) => a.firstname.localeCompare(b.firstname, 'es', {sensitivity: 'base'}))


console.log(user)

oficial 로케일 옵션은 iana , es (스페인어), de (독일어), fr (프랑스어) 에서 찾을 수 있습니다 . 약 감도 기본 수단 :

기본 문자가 다른 문자열 만 다른 것으로 비교합니다. 예 : a ≠ b, a = á, a = A


8

기본적으로 메소드 정렬을 사용하여 배열을 정렬 할 수 있지만 객체를 정렬하려면 배열의 메소드를 정렬하는 함수를 전달해야하므로 배열을 사용하는 예제를 제공합니다.

user = [{
bio: "<null>",
email: "user@domain.com",
firstname: 'Anna',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "user@domain.com",
firstname: 'Senad',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "user@domain.com",
firstname: 'Muhamed',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
}];

var ar = user.sort(function(a, b)
{
  var nA = a.firstname.toLowerCase();
  var nB = b.firstname.toLowerCase();

  if(nA < nB)
    return -1;
  else if(nA > nB)
    return 1;
 return 0;
});

마지막에 왜 0을 반환합니까?
노비타

=, 문자열이 같은 경우
Senad Meškin

그러나이 경우 else제거 하지 않아야 합니까? 그렇지 않으면 return 0읽을 수 없습니다
Nobita

2
즉 "다른"아니다, 그것은 "다른 경우"의
Senad Meškin


8

더 간결한 표기법 :

user.sort(function(a, b){
    return a.firstname === b.firstname ? 0 : a.firstname < b.firstname ? -1 : 1;
})

더 작지만 계약을 위반합니다 : sign(f(a, b)) =-sign(f(b, a))(a = b)
RiaD

3
귀국 a.firstname == b.firstname===완전성을 위해 사용해야한다
puiu

6

또한 asec 및 desc 정렬 모두에 대해 다음을 사용할 수 있습니다. 원하는 오름차순 정렬 또는 내림차순 정렬을 지정 하는 변수 SortType 이 있다고 가정하십시오 .

 users.sort(function(a,b){
            return   sortType==="asc"? a.firstName.localeCompare( b.firstName): -( a.firstName.localeCompare(  b.firstName));
        })

5

다음과 같이 일반화 된 함수를 작성할 수 있습니다

    function getSortedData(data, prop, isAsc) {
        return data.sort((a, b) => (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1));
   }

아래 매개 변수를 전달할 수 있습니다

  1. 정렬하려는 데이터
  2. 데이터별로 속성을 정렬해야합니다.
  3. 마지막 매개 변수는 부울 유형입니다. 오름차순 또는 내림차순으로 정렬할지 확인합니다.

4

시험

users.sort((a,b)=> (a.firstname>b.firstname)*2-1)


2
정렬 함수는 -1,0,1을 반환해야합니다. 이것은 -1,1 만 반환합니다.
Radu Luncasu 2016 년

@RaduLuncasu-위의 솔루션이 잘못된 결과를 나타내는 테스트 데이터 (사용자 배열)를 제공 할 수 있습니까? (내가 아는 한, 영 누락하는 것은 아무런 문제가 없음)
카밀 Kiełczewski

compareFunction (a, b)가 0을 반환하면 a와 b는 서로 변경되지 않고 모든 다른 요소에 대해 정렬됩니다.
Radu Luncasu 2018 년


@RaduLuncasu 알았지 만 그 정보가 제로가 필수라는 것을 의미하지는 않습니다. 하지만 지금까지 내가 만약 이것이 불가능 알고 - -을 표시하는 가장 좋은 방법은 작동하지 데이터를 준비입니다 예[9,8,7,6,5,1,2,3].sort((a,b) => a<b ? -1 : 1)
카밀 Kiełczewski

3

이것을 객체에 사용할 수 있습니다

transform(array: any[], field: string): any[] {
return array.sort((a, b) => a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0);}

2

간단히 말해서이 방법을 사용할 수 있습니다

users.sort(function(a,b){return a.firstname < b.firstname ? -1 : 1});

1

내장 배열 방법-을 사용할 수 있습니다 sort. 이 메소드는 콜백 메소드를 매개 변수로 사용합니다.



    // custom sort function to be passed as param/callback to the Array's sort method
    function myCustomSort(a, b) {
        return (a.toLowerCase() > b.toLowerCase()) ? 1 : -1;
    }

    // Actual method to be called by entity that needs sorting feature
    function sortStrings() {
        var op = Array.prototype.sort.call(arguments, myCustomSort);
    }

    // Testing the implementation
    var sortedArray = sortStrings("Burger", "Mayo1", "Pizza", "boxes", "Apples", "Mayo");
    console.log(sortedArray); //["Apples", "boxes", "Burger", "Mayo", "Mayo1", "Pizza"]


이 코드를 이해하기 위해 주목할 사항.

  1. 이 경우 맞춤 방법은 myCustomSort 은 각 요소 쌍 (입력 배열에서) 비교에 대해 +1 또는 -1을 반환해야합니다.
  2. 대소 문자 차이가 정렬 프로세스의 정확성에 영향을 미치지 않도록 사용자 정의 정렬 콜백 메소드에서 toLowerCase()/ toUpperCase()를 사용하십시오 .

나는 이것이 충분히 설명되기를 바랍니다. 더 많은 정보가 필요하다고 생각되면 언제든지 의견을 말하십시오.

건배!


검사보다 적거나 큰 것만 수행하고 동등 검사는 수행하지 않기 때문에 정답이 아닙니다.
스틸 브레인

또한 ~ 2011 이후에 앉아있는 답변과 비교할 때 테이블에 새로운 것을 가져 오지 않습니다.
at

1

주요 답변을 프로토 타입으로 푸시하여 키별로 정렬했습니다.

Array.prototype.alphaSortByKey= function (key) {
    this.sort(function (a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    });
    return this;
};

0

대소 문자를 구분 하기 위해 비슷한 것을 사용할 수 있습니다

users.sort(function(a, b){

  //compare two values
  if(a.firstname.toLowerCase() < b.firstname.toLowerCase()) return -1;
  if(a.firstname.toLowerCase() > b.firstname.toLowerCase()) return 1;
  return 0;

})

7
Mrchief의 답변과 동일합니다. 또 다른 단점은 toLowerCase가 두 번이 아닌 비교 당 4 번 수행된다는 것입니다.
amenthes

0

내 구현은 이전 ES 버전에서 훌륭하게 작동합니다.

sortObject = function(data) {
    var keys = Object.keys(data);
    var result = {};

    keys.sort();

    for(var i = 0; i < keys.length; i++) {
        var key = keys[i];

        result[key] = data[key];
    }

    return result;
};

0

레코드에 대해서만 명명 된 정렬 함수를 사용하려는 경우 구문은 다음과 같습니다.

let sortFunction = (a, b) => {
 if(a.firstname < b.firstname) { return -1; }
 if(a.firstname > b.firstname) { return 1; }
 return 0;
})
users.sort(sortFunction)

다음은 작동하지 않습니다.

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