陣列最大值與第二大值交換-javascript實現
阿新 • • 發佈:2019-02-04
看著這個題目,我們可能覺得很low,這麼個破題,還用的著寫篇部落格麼!我一開始也覺得不值當。直到今天我知道了這種實現方式。
如題:
var arr1 = [1,2,4,6,9,3];
交換以後就是這樣:
var arr2 = [1,2,4,9,6,3];
不要告訴我你的思路是用for迴圈挨個遍歷,找到最大的和次大的交換位置。我們不討論這種方式。如果是這樣就沒有必要寫一篇部落格了。
切入正題,你知道Math.max()這個Math物件的原生方法嗎?不知道的自行百度。這個方法可以取得一組數字的最大值。
Math.max(1,2,4,9,6,3)// =>結果是9,你造嗎!!!
但是:
var arr2 = [1,2,4,9,6,3];
Math.max(arr2)// =>結果是NaN,你造嗎!!!
Math.max()函式的引數是n個引數列表,而不接收一個數組的形式([param1[,param2[,…[,paramN]]]]),可以通過apply的方式巧妙地解決這個問題!
var arr2 = [1,2,4,9,6,3];
Math.max.apply(null,arr2)// =>結果是9,達到預期效果
我們從一些資料上得知apply的第一個引數為傳入的作用域,null表示當前作用域,第二個引數為arguments型別。但不是陣列型別。可以理解為類陣列。關於arguments的型別一會兒再做討論。
我們先解決陣列最大值和次大值交換。說到這裡了。直接上程式碼吧。
var change = '',// 儲存最大值
arr = [1,3,5,7,9],
max1 = Math.max.apply(null,arr),// 查詢最大
max1_index = arr.indexOf(max1);// 查詢最大元素索引
change = arr[max1_index];// 儲存最大值
arr[max1_index] = 0;// 把最大值置零,再次篩選最大值
console.log(arr);// 此時的陣列是[1,3,5,7,0]
var max2 = Math.max.apply(null ,arr),
max2_index = arr.indexOf(max2);
arr[max1_index] = arr[max2_index];// 次大賦值給最大
arr[max2_index] = change;// 把剛才得到的最大賦值給次大
console.log(arr);// 此時的陣列是[1,3,5,9,7]
這個問題搞定了。我們看看剛才遺留的那個關於arguments和陣列的問題。
Javascript函式中的引數arguments是個物件,而不是陣列。但它可以類似陣列那樣通過數字下表訪問其中的元素,而且它也有length屬性標識它的元素的個數。
我們可以用
Array.prototype.slice.call();
來進行arguments=》陣列的轉化
(function() {
var args = arguments;//獲取arguments
console.log(args, Object.prototype.toString.call(args)); // [1, 2, 3] "[object Arguments]"
var argsArr = Array.prototype.slice.call(args);
console.log(argsArr, Object.prototype.toString.call(argsArr)); // [1, 2, 3] "[object Array]"
}(1,2,3))
這裡需要說明一下,我們使用
Object.prototype.toString.call();
來判斷一個位置結構的型別
說到這裡,我們知道使用Array.prototype.slice.call()可以將函式的arguments物件轉化為陣列。
那麼我們接著擴充套件 Array.prototype.slice 的用法
- 字串轉化為陣列
console.log(Array.prototype.slice.call('string')); // => ["s", "t", "r", "i", "n", "g"]
- 如果引數型別為number、boolean、object的話,則會得到空陣列。
console.log(Array.prototype.slice.call({1:'44',3:'66'})); // => []
console.log(Array.prototype.slice.call(true)); // => []
console.log(Array.prototype.slice.call(22)); // => []
- 結構體要想轉化為陣列,要加上一個length屬性
console.log(Array.prototype.slice.call({0: 'zero', 1: 'one', 2: 'obj', length: 3})); // =>["zero", "one", 'obj']
- clone 陣列
var oriArr = [1,2,3],
newArr = srcArr.slice(0);
console.log(oriArr, newArr);// =>[1,2,3] [1,2,3]
console.log(oriArr == newArr);// =>false
寫了這麼多,主要因apply這個方法而起。
本文涉及到的知識點:
- Math.max(1,2,4,9,6,3)
- Math.max.apply(null,arr)
- Object.prototype.toString.call()
- Array.prototype.slice.call()
- arr.slice()