javascript - 关于JS的算法题
怪我咯
怪我咯 2017-04-11 12:57:54
0
4
349
function largestOfFour(arr) {
  return arr.map(Function.apply.bind(Math.max, null));
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

这Function.apply.bind(Math.max, null) 该怎么理解??

怪我咯
怪我咯

走同样的路,发现不同的人生

reply all(4)
伊谢尔伦

假如直接这样

function largestOfFour(arr) {
  return arr.map(Math.max);
}

输出一定是四个NAN
因为Math.max的参数不能是数组,一定是Math.max(1,2,3)这样的格式
所以传给map的callback一定是可以处理数组的每一项由[1,2,3]变成1,2,3
来看函数:

function largestOfFour(arr) {
  return arr.map(Function.apply.bind(Math.max, null));
}

单独拿出来看

Function.apply.bind(Math.max, null)

Function.apply里面的this被替换成Math.max,同时参数传过去null

这时候arr里面的每一项数组作为参数传递给Function.apply,由Math.max处理,而数组当做apply的第二个参数正好处理

不知道我解释的清不清晰~~

巴扎黑
function largestOfFour(arr) {
  return arr.map(func);
}

largestOfFour(这个Four其实是多余的,因为并不一定得是4个元素,1-n个元素都行)这个函数目的在于求一个二维数组中每个一维数组中的最大值。

那么我们正常思路是什么呢,首先,肯定会用到map,这样我们只需要编写一个函数,这个函数接受一个数组,并返回一个数组中的最大值。但是已经有现成的max函数了,他虽然能返回最大值,但是接收的并不是一个数组,而是一连串的数字。这不符合我们的应用场景,但是程序猿是懒惰的,于是我们想,能不能稍微改造下这个max函数,利用他产生一个函数,这个函数接收的参数变成一个数组,而不是一连串数字。
自然,我们就想到了apply,因为他可以将一个数组作为arguments传给一个函数。简单的小测试如下:

function func(v1, v2, v3) {
   console.log(v1 + ',' + v2 + ',' + v3);
}

func.apply(null, [1,2,3]); // 输出1,2,3

所以我们可以写出这样


return arr.map(function(ele) {return Math.max.apply(null, ele);});

但是这样我们创建了一个匿名函数,我们还想简化怎么办(虽然我比较喜欢这种写法,看起来简单很多。。)

好,现在确定下我们的目标,我们想得到一个函数。这个函数要完全基于Math.max,也就是函数体要相同(但我们不想要一个匿名函数去包裹他),这个时候我们就只能调用Function这个所有函数的父类了,通过他来创建函数。

但是我们不能直接Function.apply(Math.max)这样就已经调用了max了,我们现在需要的是一个函数的引用,而不是调用他。于是我们想到了bind,他能返回一个函数的副本,并且能改变this指向。

Function.apply.bind(Math.max, undefined, [2, 3, 4, 5, 6])()
// or
Function.apply.bind(Math.max, undefined)([2, 3, 4, 5, 6])

即构建一个与Math.max函数体内容相同的函数,这里的undefined为Math.max里的this指向(bind的第一个参数为调用apply时的this指向,这里为Math.max,即构建一个与Math.max函数体内容相同的函数。第二个参数为追加在arguments之前的参数,如


function aa(){console.log(arguments);}

aa.bind(null, 22)(33); // 输出22, 33

具体可以看看bind的用法这里)。

[2, 3, 4, 5, 6]为调用Math.max时的arguments指向。

上例中的[2, 3, 4, 5, 6]是调用map函数时参数列表中的第一个参数(第一个参数为数组中的每个值,在第一次调用的时候即是题目中的[4, 5, 1, 3])

这样,就实现了我们想要的功能,即改造Math.max,利用他实现一个函数,这个函数接收一个数组作为参数,返回数组中的最大值。

左手右手慢动作

这么理解:

function largestOfFour(arr) {
  return arr.map(function(val) {
      return Math.max.apply(null, val);
  });
}

确实有点绕儿

洪涛

https://segmentfault.com/q/10...
看这里。

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template