実際のビジネスでは、定義された配列の順序を変更することが必要になることがよくあります。 JavaScript には、配列をソートできる 2 つのメソッドが付属しています。これら 2 つのメソッドは、sort() と reverse() です。今日はこれら 2 つの方法について学びましょう。
sort() メソッドは、配列の要素を適切にソートし、配列を返します。デフォルトでは、sort() メソッドは配列項目を昇順にソートします。つまり、最小値は前方にあり、最大値は後方にあります。並べ替えを実装するには、sort() メソッドで各配列項目の toString() 変換メソッドを呼び出し、結果の文字列を比較して並べ替え方法を決定します。
まず簡単な例を見てみましょう:
var arr = ['hello','jame','Jack','dog']; // 定义一个数组console.log(arr.sort()); // ["Jack", "dog", "hello", "jame"]
前に述べたように、sort() メソッドがパラメーターを何も呼び出さない場合、メソッドは昇順、つまりアルファベット順に並べられるため、結果は次のようになります。も正しいです。
次に、数値の配列配置の例を見てみましょう:
var arr = [1,5,10,22]; // 定义一个数组console.log(arr.sort()); // [1, 10, 22, 5]
この例では配列の順序に問題はありませんが、sort() メソッドが配列の順序を変更した後、順序が間違っています。どうしてこれなの?
関連ドキュメントを確認したところ、sort() メソッド: パラメーターが省略された場合、配列項目はまず toString() 関数に従って値を文字列に変換して比較されます。 UNICODE に基づいてソートされます。 前の例と同様に、「ジャック」は「犬」の前にランクされます。数値を並べ替えると、最初に文字列に変換されるため、「10」と「22」の後に「5」が表示され、「10」と「22」は両方とも「5」の前になります。
charCodeAt() を使用して検証できます:
"Jack".charCodeAt() ==> 74"dog".charCodeAt() ==> 100"5".charCodeAt() ==> 53"10".charCodeAt() ==> 49"22".charCodeAt() ==> 50
この場合、これは最良の解決策ではありません。幸いなことに、sort() メソッドは比較関数 CompareFunction をパラメーターとして受け入れることができるため、どの値がどの値の前に来るかを指定できます。
CompareFunction を指定すると、関数呼び出しの戻り値に応じて配列がソートされます。比較関数 CompareFunction は 2 つのパラメーター a と b を受け取ります。 a と b は比較される 2 つの要素です:
CompareFunction(a,b) 関数:
function compareFunction (a, b) { if (a < b) { return -1; // a排在b的前面 } else if (a > b) { return 1; // a排在b的后面 } else { return 0; // a和b的位置保持不变 }}
この関数は適用できますCompareFunction(a ,b) である限り、ほとんどのデータ型にこの関数はパラメータとして sort() メソッドに渡すことができます。前の例のため:
var arr = [1,5,10,22]; // 定义一个数组arr.sort(compareFunction); // 将compareFunction函数作为参数传给 sort()console.log(arr); // [1, 5, 10, 22]
配列 arr は正しい昇順を維持します。実際、compareFunction(a,b) を使用して配列を降順に並べ替えることができます。必要なのは、compareFunction 関数の戻り値を調整することだけです。同じ入力で結果を比較します。そうでない場合、並べ替えられた結果は不定になります。
上で述べたように、sort() メソッドが CompareFunction(a,b) パラメーターを渡すと、戻り値が 3 つになる可能性があるため、次の記述は間違っています:
function compareFunction (a, b){ if (a < b) { return 1; // a排在b的后面 } else if (a > b) { return -1; // a排在b的前面 } else { return 0; // a 和 b 保持位置不变 }}var arr = [1, 5, 10, 22]; //定义一个数组arr.sort(compareFunction); // 将compareFunction函数作为参数传给sort()console.log(arr); // [22, 10, 5, 1]
考えられる結果は [5, 21, 11] です。 、10、9、8、7、6、4、3、0]、これは正しい結果ではありません。これは、 return a < b は 1 または 0 に相当する true または false の 2 つの値のみを返すためです。 -1 ではありません。
数値型または valueOf() メソッドが数値型を返すオブジェクト型の場合は、より単純な比較関数を使用できます。
function compareFunction (a, b) { return a < b; }var arr = [21, 0, 3, 11, 4, 5, 6, 7, 8, 9, 10];arr.sort(compareFunction);console.log(arr); // [5, 21, 11, 10, 9, 8, 7, 6, 4, 3, 0]
結果が希望通りかどうか見てみましょう:
// ascSort(a,b)传给sort(),数字数组作升序排列function ascSort (a, b) { // a和b是数组中相邻的两个数组项 return a - b; // 如果 return -1, 表示a小于b,a排列在b的前面 // 如果 return 1, 表示a大于b,a排列在b的后面 // 如果 return 0, 表示a等于b,a和b的位置保持不变}// desSort(a,b)传给sort(),数字数组作降序排列function desSort (a, b) { // a和b是数组中相邻的两个数组项 return b - a; // 如果 return -1, 表示b小于a,b排列在a的前面 // 如果 return 1, 表示b大于a, b排列在a的后面 // 如果 return 0, 表示 b等于a, b和a的位置保持不变}
文字配列の配置
var arr = [1,4,10,3], arr2 = [100,12,99,3,2]; //定义数组arr.sort(ascSort); // 将ascSort函数传给sort()arr2.sort(desSort); // 将desSort函数传给sort()console.log(arr); // [1, 3, 4, 10]console.log(arr2); // [100, 99, 12, 3, 2]
Chrome によって出力される結果:
var stringArray = ['blue', 'Humpback', 'Beluga'];stringArray.sort();console.log('字符串数组stringArray:' + stringArray);
数値文字列配列配置
字符串数组stringArray:Beluga,Humpback,blue
Chromeで出力された結果:
var numericStringArray = ['80', '9', '700'];function compareFunction (a, b) { return a - b;}console.log('不指定比较函数的数字字符串数组排列:' + numericStringArray.sort());console.log('指定比较函数的数字字符串数组排列:' + numericStringArray.sort(compareFunction));
数値配列の配置
不指定比较函数的数字字符串数组排列:700,80,9指定比较函数的数字字符串数组排列:9,80,700
Chrome によって出力された結果:
var numberArray = [80, 9, 700];function compareFunction (a, b) { return a - b;}console.log('不指定比较函数的数字数组排列:' + numberArray.sort());console.log('指定比较函数的数字数组排列:' + numberArray.sort(compareFunction));
数値と数値文字列の混合配列配置
不指定比较函数的数字字符串数组排列:700,80,9指定比较函数的数字字符串数组排列:9,80,700
Chrome によって出力された結果:
不指定比较函数的数组排列:1,200,40,5,700,80,9指定比较函数的数组排列1,5,9,40,80,200,700
除了给数字数组进行升序或降序排列之外,还可以定义一个随机函数,实现数组的随机排列。定义的随机函数返回正数或者负数,并表将随机函数传给 sort() 方法,此时 sort() 方法根据随机函数返回的正负数来决定两个值之前的位置。
var randomArray = [9,0,23,8,3,5];function randomSort(a, b) { return Math.random() - 0.5;}console.log(randomArray.sort(randomSort));// [8, 5, 9, 0, 23, 3]// [8, 3, 5, 0, 23, 9]// [8, 5, 0, 3, 9, 23]
对于对象数组排列,我们同样需要先写一个构造函数:
function objectSort(property, desc) { //降序排列 if (desc) { return function (a, b) { return (a[property] > b[property]) ? -1 : (a[property] < b[property]) ? 1 : 0; } } return function (a, b) { return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; }}var myArray = [ { "name": "John Doe", "age": 29 }, { "name": "Anna Smith", "age": 24 }, { "name": "Peter Jones", "age": 39 }]console.log(myArray.sort(objectSort('name',true))); // 按object中的name的降序排列
来看看Chrome输出的前后结果:
另外,只需要改变比较函数 objectSort() 中的 desc 参数值为 flase ,数组就会按 object 指定的 property 属性降序排列:
console.log(myArray.sort(objectSort('age',false))); //按objcet中的age升序排列
Chrome输出的前后结果:
除此之外,还有其的对比较函数,如下所示:
function dynamicSort(property) { var sortOrder = 1; if(property[0] === "-") { sortOrder = -1; property = property.substr(1); } return function (a,b) { var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; return result * sortOrder; }}console.log(myArray.sort(dynamicSort('age'))); // 按升序排列console.log(myArray.sort(dynamicSort('-age'))); // 按降序排列
上面介绍的是按一个属性进行排序,但很多时候,希望按多个属性排序,那么比较函数需要做一定的调整:
function dynamicSortMultiple() { var props = arguments; return function (obj1, obj2) { var i = 0, result = 0, numberOfProperties = props.length; while(result === 0 && i < numberOfProperties) { result = dynamicSort(props[i])(obj1, obj2); i++; } return result; }}myArray.sort(dynamicSortMultiple('name','-age'));
reverse() 方法相对而言要简单得多,它就是用来颠倒数组中元素的位置,并返回该数组的引用。比如我们有一个数组:
var myArray = ["Airen","W3cplus","Blog"];console.log(myArray.reverse()); // ["Blog", "W3cplus", "Airen"]
本文主要介绍了数组中元素项的排序方法。而主要详细介绍的是 sort() 方法。通过给 sort() 方法传递不同的比较函数,我们可以实现 字符串数组 、 数字数组 、 数字和数字字符串混合数组 、 对象数组 等按顺序( 升序 或 降序 )排列。
常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。