Urutkan array berdasarkan nama depan (berdasarkan abjad) dalam Javascript


647

Saya mendapat sebuah array (lihat di bawah untuk satu objek dalam array) yang perlu saya urutkan berdasarkan nama depan menggunakan JavaScript. Bagaimana saya bisa melakukannya?

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

Jawaban:


1068

Misalkan Anda memiliki array users. Anda dapat menggunakan users.sortdan meneruskan fungsi yang membutuhkan dua argumen dan membandingkannya (pembanding)

Itu harus kembali

  • sesuatu yang negatif jika argumen pertama kurang dari detik (harus ditempatkan sebelum argumen kedua dalam array yang dihasilkan)
  • sesuatu yang positif jika argumen pertama lebih besar (harus ditempatkan setelah argumen kedua)
  • 0 jika kedua elemen tersebut sama.

Dalam kasus kami jika dua elemen adalah adan bkami ingin membandingkan a.firstnamedanb.firstname

Contoh:

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

Kode ini akan bekerja dengan tipe apa pun.

Perhatikan bahwa dalam "kehidupan nyata" ™ Anda sering ingin mengabaikan huruf besar-kecil, urutkan dengan benar diakritik, simbol aneh seperti ß, dll saat Anda membandingkan string, jadi Anda mungkin ingin menggunakannya localeCompare. Lihat jawaban lain untuk kejelasan.


5
Friggin luar biasa ... Saya sedang mengurutkan nodelist oleh id ... bekerja seperti pesona. Terima kasih!
Cody

74
Bagi mereka yang datang di kemudian hari, jawaban Mrchief lebih baik karena tidak sensitif huruf.
mlienau

25
@ Mlienau, saya tidak akan menyebutnya lebih baik atau lebih buruk. Ini hanya lain
RiaD

19
@RiaD cukup adil. Hanya tidak bisa memikirkan banyak kasus menyortir item secara alfabet termasuk casing, di mana 'Zebra' muncul dalam daftar sebelum 'apel', akan sangat berguna.
mlienau

15
Kode ini hanya akan berfungsi di negara-negara berbahasa Inggris. Di negara lain Anda harus menggunakan jawaban ovunccetin denganlocaleCompare .
Spoike

546

Kode terpendek dengan ES6!

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

String.prototype.localeCompare () dukungan dasar bersifat universal!


27
Sejauh ini jawaban terbaik jika Anda tinggal di 2017
nathanbirrell

52
Jawaban terbaik juga jika Anda hidup pada tahun 2018;)
Simone

49
Mungkin akan menjadi jawaban terbaik untuk 2019 juga.
Ahmad Maleki

23
2020 mungkin? atau naaa?
kspearrin

15
ah manusia, pada 2030 bumi banjir dan ini hanya berfungsi di pegunungan.
Starfs

343

Sesuatu seperti ini:

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
Saat menyortir string 'toLowerCase ()' sangat penting - huruf kapital dapat memengaruhi sortir Anda.
MarzSocks

3
Jika ada orang lain yang bertanya-tanya apa dampak toLowerCase, itu tidak banyak:'a'>'A' //true 'z'>'a' //true 'A'>'z' //false
SimplGy

14
@SimplGy Saya berpendapat bahwa dampaknya sedikit lebih dari yang Anda berikan kredit untuk itu. Misalnya, seperti yang dinyatakan dalam komentar pada jawaban yang diterima, penting untuk mengetahui apakah fungsi sortir Anda akan mengurutkan string 'Zebra'lebih tinggi daripada string 'apple', yang akan dilakukan jika Anda tidak menggunakan .toLowerCase().
PrinceTyke

1
@PrinceTyke ya itu pria kasus yang baik. 'Z' < 'a' // truedan'z' < 'a' // false
SimplGy

2
Semua poin yang valid dan saya katakan penyortiran selalu merupakan hal yang "tergantung". Jika Anda mengurutkan berdasarkan nama, sensitivitas huruf mungkin tidak masalah. Dalam kasus lain mungkin. Bagaimanapun, saya pikir mengadopsi ke situasi spesifik seseorang tidak sulit setelah Anda mendapatkan ide inti.
Mrchief

336

Jika string dibandingkan berisi karakter unicode Anda dapat menggunakan localeComparefungsi dari Stringkelas seperti berikut ini:

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

3
String.localeCompare tidak mendukung Safari dan IE <11 :)
CORSAIR

13
@CORSAIR didukung, hanya parameter kedua dan ketiga yang tidak didukung.
Codler

6
@CORSAIR penggunaan dalam contoh ini didukung di semua browser IE utama: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… . LocaleCompare juga memperhitungkan kapitalisasi akun, jadi saya pikir implementasi ini harus dianggap sebagai praktik terbaik.
Matt Jensen

9
users.sort ((a, b) => a.firstname.localeCompare (b.firstname)) // Pendek dan manis versi ES6!
Nachiketha

4
tank saudara. dalam penggunaan ES6users.sort((a, b) => a.name.localeCompare(b.name))
Mohmmad Ebrahimi Aval

32

ES6 satu liner kecil yang bagus:

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

2
Yang ini tidak lengkap karena tidak menangani nilai yang sama dengan benar.
Karl-Johan Sjögren

1
Tentu saja, terima kasih telah melihatnya, saya telah menambahkan cek untuk nilai yang cocok
Sam Logan

tidak buruk saya kira jika Anda benar-benar ingin semuanya dalam satu baris, terner yang bersarang menjadi membingungkan untuk dibaca
russter

24

Kita dapat menggunakan localeCompare tetapi perlu memeriksa kunci juga untuk nilai falsey

Kode di bawah ini tidak akan berfungsi jika satu entri memiliki nama yang hilang.

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

Jadi kita perlu memeriksa nilai falsey seperti di bawah ini

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

ATAU

kita bisa menggunakan lodash, ini sangat sederhana. Ini akan mendeteksi nilai-nilai yang dikembalikan yaitu apakah angka atau string dan melakukan pengurutan yang sesuai.

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

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


2
Lodash cukup rapi! Belum pernah mendengarnya sebelumnya. Bagus sekali!
Derk Jan Speelman

15

underscorejs menawarkan fungsi _.sortBy yang sangat bagus:

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

atau Anda dapat menggunakan fungsi pengurutan khusus:

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

2
contoh kedua melibatkan string yang dikembalikan. Apakah sortBymendeteksi nilai yang dikembalikan adalah string dan dengan demikian melakukan pengurutan alfabet? Terima kasih
superjos

12

Jika kita menyortir nama atau sesuatu dengan karakter khusus, seperti ñ atau áéíóú (commons dalam bahasa Spanyol) kita dapat menggunakan params locales ( es untuk bahasa Spanyol dalam kasus ini) dan opsi seperti ini:

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)

Pilihan lokasi resmi dapat ditemukan di sini di iana , es (spanyol), de (Jerman), fr (Prancis). Tentang basis sensitivitas berarti:

Hanya string yang berbeda dalam huruf dasar yang dibandingkan sebagai tidak sama. Contoh: a ≠ b, a = á, a = A.


8

Pada dasarnya Anda dapat mengurutkan array dengan metode sortir, tetapi jika Anda ingin mengurutkan objek maka Anda harus melewati fungsi untuk mengurutkan metode array, jadi saya akan memberi Anda contoh menggunakan array Anda

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

mengapa mengembalikan 0 di akhir?
Nobita

=, ketika string sama
Senad Meškin

tetapi dalam kasus itu tidakkah elseharus dihapus? Kalau tidak, itu return 0tidak akan pernah dibaca
Nobita

2
itu bukan "lain", itu "lain kalau"
Senad Meškin


8

Notasi yang lebih ringkas:

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

itu lebih ringkas tetapi melanggar kontraknya: sign(f(a, b)) =-sign(f(b, a))(untuk a = b)
RiaD

3
return a.firstname == b.firstnameharus digunakan ===untuk kelengkapan
puiu

6

juga untuk penguraian asec dan desc, Anda dapat menggunakan ini: misalkan kita memiliki SortType variabel yang menentukan pengurutan atau pengurutan yang Anda inginkan:

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

5

Fungsi umum dapat ditulis seperti di bawah ini

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

Anda dapat melewati parameter di bawah ini

  1. Data yang ingin Anda urutkan
  2. Properti dalam data olehnya harus disortir
  3. Parameter terakhir adalah tipe boolean. Ia memeriksa apakah Anda ingin menyortir dengan naik atau turun

4

mencoba

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


2
fungsi sortir harus mengembalikan -1,0,1. ini hanya mengembalikan -1,1.
Radu Luncasu

@RaduLuncasu - dapatkah Anda memberikan data uji (array pengguna) yang menunjukkan bahwa solusi di atas memberikan hasil yang salah? (Sejauh yang saya tahu, kehilangan nol bukanlah masalah)
Kamil Kiełczewski

Jika fungsi perbandingan (a, b) mengembalikan 0, biarkan a dan b tidak berubah terhadap satu sama lain, tetapi diurutkan sehubungan dengan semua elemen yang berbeda.
Radu Luncasu


@ RaduLuncasu ok, tapi informasi itu tidak berarti nol wajib. Cara terbaik untuk menunjukkannya adalah menyiapkan data yang tidak berfungsi - tetapi sejauh yang saya tahu ini tidak mungkin - misalnya[9,8,7,6,5,1,2,3].sort((a,b) => a<b ? -1 : 1)
Kamil Kiełczewski

3

Anda dapat menggunakan ini untuk objek

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

hanya dengan kata-kata Anda dapat menggunakan metode ini

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

1

Anda dapat menggunakan metode larik bawaan - sort. Metode ini menggunakan metode panggilan balik sebagai param



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


Poin-Poin Penting yang perlu diperhatikan untuk memahami kode ini.

  1. Metode kustom, dalam hal ini,, myCustomSortharus mengembalikan +1 atau -1 untuk setiap pasangan elemen (dari array input) perbandingan.
  2. Gunakan toLowerCase()/ toUpperCase()dalam metode panggilan balik penyortiran khusus sehingga perbedaan huruf besar / kecil tidak mempengaruhi kebenaran proses penyortiran.

Saya harap penjelasan ini cukup jelas. Jangan ragu untuk berkomentar jika menurut Anda, diperlukan lebih banyak info.

Bersulang!


Bukan jawaban yang tepat karena hanya melakukan kurang dari dan lebih besar dari cek dan bukan pemeriksaan yang sama.
Steel Brain

itu juga tidak membawa enything baru ke meja, dibandingkan dengan salah satu jawaban yang telah duduk di sana sejak ~ 2011.
amenthes

1

Dorong jawaban teratas menjadi prototipe untuk disortir berdasarkan kunci.

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

Anda dapat menggunakan sesuatu yang serupa, untuk menghilangkan case sensitif

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
Jawaban yang sama dengan yang dilakukan oleh Mrchief. Dengan kerugian lebih lanjut bahwa toLowerCase dilakukan empat kali per perbandingan, bukan dua kali.
amenthes

0

Implementasi saya, berfungsi baik di versi ES yang lebih lama:

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

Sekadar catatan, jika Anda ingin memiliki fungsi sortir bernama, sintaksnya adalah sebagai berikut:

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

Perhatikan bahwa berikut ini TIDAK berfungsi:

users.sort(sortFunction(a,b))
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.