Ben JavaScript sıralamak gerekir dizeleri bir dizi var, ama büyük / küçük harf duyarsız bir şekilde. Bu nasıl yapılır?
Ben JavaScript sıralamak gerekir dizeleri bir dizi var, ama büyük / küçük harf duyarsız bir şekilde. Bu nasıl yapılır?
Yanıtlar:
İçinde (neredeyse :) bir astar
["Foo", "bar"].sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
Hangi sonuçlar
[ 'bar', 'Foo' ]
Süre
["Foo", "bar"].sort();
sonuç
[ 'Foo', 'bar' ]
return a.localeCompare(b, 'en', {'sensitivity': 'base'});
toLowerCase()
zaman localeCompare
zaten bazı durumlarda varsayılan olarak bunu yapıyor. Buradan geçirilecek parametreler hakkında daha fazla bilgiyi buradan edinebilirsiniz: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
myArray.sort(
function(a, b) {
if (a.toLowerCase() < b.toLowerCase()) return -1;
if (a.toLowerCase() > b.toLowerCase()) return 1;
return 0;
}
);
DÜZENLEME: Lütfen bunu aklınızda performans göstermek yerine tekniği göstermek için yazdığımı unutmayın. Daha kompakt bir çözüm için lütfen @Ivan Krechetov'a bakınız.
toLowerCase
her dizede iki kez çağırabilir ; dizenin indirgenmiş sürümlerinde değişkenler için daha verimli olur.
.toLowerCase()
dizideki her öğe için birden çok kez çağırabilir . Örneğin, 10 öğeyi ters sırada sıralarken 45 karşılaştırma işlevini çağırır. var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
Bu eski soruyu tekrar ziyaret etmenin zamanı geldi.
Güvenilir çözümler kullanmamalısınız toLowerCase
. Bunlar verimsiz ve basitçe çalışmayan bazı diller (örneğin Türkçe) içinde. Bunu tercih et:
['Foo', 'bar'].sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))
Tarayıcı uyumluluğu için belgelere bakın ve sensitivity
seçenek hakkında bilinmesi gerekenler.
arr.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a == b) return 0;
if (a > b) return 1;
return -1;
});
return a === b ? 0 : a > b ? 1 : -1;
["111", "33"]
, geri dönmesini isteyebiliriz, ["111", "33"]
çünkü 1 karakter kodu sıralamasında 1 önce gelir. Ancak, bu ["33", "111"]
sayıdaki işlev , sayı sayıdan 33
küçük olduğu için geri döner 111
.
"33" > "111" === true
ve 33 > 111 === false
. İstendiği gibi çalışır.
Yeni Intl.Collator().compare
olanı da kullanabilirsiniz , her MDN için dizileri sıralarken daha verimlidir . Dezavantajı, eski tarayıcılar tarafından desteklenmemesidir. MDN, Safari'de hiç desteklenmediğini belirtir. Intl.Collator
Desteklendiğini belirttiği için doğrulamanız gerekiyor .
Büyük dizileri sıralama gibi çok sayıda dizeyi karşılaştırırken, bir Intl.Collator nesnesi oluşturmak ve compar özelliği tarafından sağlanan işlevi kullanmak daha iyidir
["Foo", "bar"].sort(Intl.Collator().compare); //["bar", "Foo"]
Giriş dizisindeki öğelerin sırasından bağımsız olarak aynı sırayı garanti etmek istiyorsanız, kararlı bir sıralama:
myArray.sort(function(a, b) {
/* Storing case insensitive comparison */
var comparison = a.toLowerCase().localeCompare(b.toLowerCase());
/* If strings are equal in case insensitive comparison */
if (comparison === 0) {
/* Return case sensitive comparison instead */
return a.localeCompare(b);
}
/* Otherwise return result */
return comparison;
});
Davayı Normale .sort()
ile .toLowerCase()
.
Elvis operatörünü de kullanabilirsiniz:
arr = ['Bob', 'charley', 'fudge', 'Fudge', 'biscuit'];
arr.sort(function(s1, s2){
var l=s1.toLowerCase(), m=s2.toLowerCase();
return l===m?0:l>m?1:-1;
});
console.log(arr);
verir:
biscuit,Bob,charley,fudge,Fudge
LocaleCompare yöntemi muhtemelen iyi ...
Not: Elvis operatörü, genellikle ödevle birlikte, başka bir durumda kısa bir 'üçlü operatör' şeklindedir.
?: Yana bakarsanız, Elvis gibi görünür ...
yani:
if (y) {
x = 1;
} else {
x = 2;
}
kullanabilirsiniz:
x = y?1:2;
yani y doğru olduğunda, 1 değerini (x'e atama için), aksi takdirde 2'yi (x'e atama için) döndürün.
x = y ? y : z
bunu yapabilirsiniz x = y ?: z
. Javascript'in gerçek bir Elvis operatörü yok, ancak x = y || z
benzer bir şekilde kullanabilirsiniz.
Diğer yanıtlar dizinin dize içerdiğini varsayar. Benim yöntem daha iyidir, çünkü dizi null, undefined veya diğer dizeler içermese bile çalışacaktır.
var notdefined;
var myarray = ['a', 'c', null, notdefined, 'nulk', 'BYE', 'nulm'];
myarray.sort(ignoreCase);
alert(JSON.stringify(myarray)); // show the result
function ignoreCase(a,b) {
return (''+a).toUpperCase() < (''+b).toUpperCase() ? -1 : 1;
}
null
'Nulk' ve 'nulm' arasında sıralanır. Ama undefined
olacak hep en son sıralanır.
(''+notdefined) === "undefined"
yani "z" den önce
Array.prototype.sort
: | çünkü (''+notdefined) === "undefined"
gerçekten doğru olan kısım doğrudur ... yani, sırayı tersine çevirmek için sıralama işlevinde -1 ve 1'i çevirirseniz, tanımsız yine de sonuna kadar sıralar. Ayrıca, bir sıralama dizisi bağlamının dışında karşılaştırma işlevini kullanırken de dikkate alınması gerekir (bu soruya geldiğimde olduğu gibi).
Array.prototype.sort
tanımı düşünerek - birkaç yorum daha. İlk olarak, (''+a)
- ECMAScript toString()
öğesinin CompareFn'ye geçirilmeden önce çağrılması gerekmez. İkincisi, eşit (durum için eşit-ancak-dahil) dizeleri karşılaştırırken ignoreCase
geri 1
dönmesi, belirtimin yinelenen değerler varsa sonucu tanımlamaması anlamına gelir (muhtemelen bazı gereksiz takaslarla iyi olacaktır, sanırım).
undefined
, herhangi bir x x <undefined ve x> undefined için ikisi de yanlış . Bu undefined
her zaman sonuncudur, sıralama türünün bir yan ürünüdür. ('' + A) 'yı basitçe a olarak değiştirmeye çalıştım, ancak başarısız oluyor. Anladım TypeError: a.toUpperCase is not a function
. Görünüşe toString
edilir değil compareFn aramadan önce aradı.
undefined
Fn asla çağrılmaz
ES6 sürümü:
["Foo", "bar"].sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }))
Kabul edilen cevabı desteklemek için, aşağıdaki fonksiyonun orijinal dizideki değerleri sıralanacak şekilde değiştirdiğini eklemek istiyorum, böylece sadece küçük harf sıralamakla kalmayacak, aynı zamanda büyük harf değerleri de küçük harfe dönüştürülecektir. Bu benim için bir sorun, çünkü Mary'yi mary'nin yanında görmek istememe rağmen, Mary'nin ilk değeri vakasının küçük harfe değiştirilmesini istemiyorum.
myArray.sort(
function(a, b) {
if (a.toLowerCase() < b.toLowerCase()) return -1;
if (a.toLowerCase() > b.toLowerCase()) return 1;
return 0;
}
);
Deneylerimde, kabul edilen yanıttan aşağıdaki işlev doğru şekilde sıralanır, ancak değerleri değiştirmez.
["Foo", "bar"].sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
Anlamak için mücadele ettiyseniz, bu yardımcı olabilir:
var array = ["sort", "Me", "alphabetically", "But", "Ignore", "case"];
console.log('Unordered array ---', array, '------------');
array.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
console.log("Compare '" + a + "' and '" + b + "'");
if( a == b) {
console.log('Comparison result, 0 --- leave as is ');
return 0;
}
if( a > b) {
console.log('Comparison result, 1 --- move '+b+' to before '+a+' ');
return 1;
}
console.log('Comparison result, -1 --- move '+a+' to before '+b+' ');
return -1;
});
console.log('Ordered array ---', array, '------------');
// return logic
/***
If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.
If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
If compareFunction(a, b) is greater than 0, sort b to a lower index than a.
***/
arr.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
if( a == b) return 0;
if( a > b) return 1;
return -1;
});
Yukarıdaki fonksiyonda, sadece küçük harf a ve b değeri ne zaman karşılaştırırsak, güzel bir sonuç elde edemeyiz.
Örneğin, dizi [A, a, B, b, c, C, D, d, e, E] ise ve yukarıdaki işlevi kullanırsak, tam olarak bu diziye sahibiz. Hiçbir şey değişmedi.
Sonucun [A, a, B, b, C, c, D, d, E, e] olması için, iki küçük harf değeri eşit olduğunda tekrar karşılaştırmalıyız:
function caseInsensitiveComparator(valueA, valueB) {
var valueALowerCase = valueA.toLowerCase();
var valueBLowerCase = valueB.toLowerCase();
if (valueALowerCase < valueBLowerCase) {
return -1;
} else if (valueALowerCase > valueBLowerCase) {
return 1;
} else { //valueALowerCase === valueBLowerCase
if (valueA < valueB) {
return -1;
} else if (valueA > valueB) {
return 1;
} else {
return 0;
}
}
}
Ben dize diziler üzerinde .sortIgnoreCase () çağırabilirsiniz böylece bir çoklu doldurma üst yanıt sarılmış
// Array.sortIgnoreCase() polyfill
if (!Array.prototype.sortIgnoreCase) {
Array.prototype.sortIgnoreCase = function () {
return this.sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
};
}
Dizelerinizi sarın / /i
. Bu, kasayı yoksaymak için normal ifadeyi kullanmanın kolay bir yoludur