数组最大值与第二大值交换-javascript实现

时间:2022-12-15 11:27:42

看着这个题目,我们可能觉得很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()