通过示例了解箭头函数
Understanding Arrow functions with an Example
我无法理解使用箭头函数和 .every() 方法的编码挑战的解决方案,希望更有知识的人可以解释发生了什么。挑战在于检查网格以查看它是否代表真正的数独板。我理解第一部分连接和乘以一个 row/col/square,但无法理解后面的部分...
// True, if product of #s in row is 9!
p = a => eval(a.join("*")) == (1*2*3*4*5*6*7*8*9);
// Check each row, column and 3 block grid using p()
sudoku = grid =>
grid.every((r,i) =>
p(r) &&
p(grid.map(r => r[i])) &&
p(r.map((_,j) => grid[3*(i/3|0)+(j/3|0)][3*(i%3)+(j%3)]) ) )
感谢您的帮助!
sudoku = grid =>
grid.every((r,i) =>
p(r) &&
p(grid.map(r => r[i])) &&
p(r.map((_,j) => grid[3*(i/3|0)+(j/3|0)][3*(i%3)+(j%3)]) ) )
- 对于网格中的每个项目 r,计算 p(r)。如果它是真的那么第二部分将被评估
grid.map(r => r[i])
将被评估,这反过来将遍历所有网格项目和 return 它们的 ith 元素的数组.
现在如果p(grid.map(r => r[i]))
为真则后面的部分将被评估。
最后 r.map((_,j) => grid[3*(i/3|0)+(j/3|0)][3*(i%3)+(j%3)]) )
将被执行,但前提是前两个条件为真。
这也将 return 一个网格数组项,取决于 i 和 j 的值。
So key points here is the usage of &&
A && B
将 return B 如果 A 的计算结果为真(并且仅当 A 为真时才计算 B)
在大多数情况下,箭头函数只是一个函数。两者之间唯一真正的区别是 this
在使用箭头函数时从外部上下文中保留下来,而 this
是用于使用普通函数调用函数的 this
.
function A() {
this.v = 1;
this.a = () => console.log(this.v);
this.b = function () { console.log(this.v) };
}
// Both will use `obj` as `this`
const obj = new A();
obj.a();
obj.b();
// The arrow-function `a()` will keep the same `this` as above, `obj` will change.
const obj2 = { v: 2 };
obj2.a = obj.a;
obj2.b = obj.b;
obj2.a();
obj2.b();
另一个可能会让你失望的区别是箭头函数,如果它只需要一行,你可以省略大括号 ({}
) 它会 return价值。即,
a => 1
等同于:
function (a) { return 1; }
在此示例代码中,作为箭头函数或常规函数没有区别,因为未调用 this
。
代码的作用是:
grid.every((r, i) =>
查看 grid
中的每个元素,并一直持续到 returns true
。 r
是 grid
的当前值,i
是它正在处理的当前索引。
grid.map(r => r[i])
实际上只是从 r
获取 i-th
值并 returning 它。这将用于检查二维数组的对角线。 (所以它得到 grid[0][0]
、grid[1][1]
,等等)。
r.map((_, j) => grid[math])
然后只是遍历 r
中的每个元素,并使用来自外循环的当前 i
索引和 j
索引获取一些元素(基于该数学)来自 r
。使用 _
作为参数名称是一种常见的约定,表示您不关心该参数。
似乎数独的输入数据是二维数组,如下所示:
let grid = [
[2,4,1,7,6,8,5,3,9],
[5,7,3,9,2,4,1,8,6],
[8,9,6,5,3,1,7,4,2],
[7,3,4,2,9,5,6,1,8],
[1,8,9,4,7,6,3,2,5],
[6,5,2,8,1,3,4,9,7],
[4,6,5,3,8,2,9,7,1],
[3,2,7,1,5,9,8,6,4],
[9,1,8,6,4,7,2,5,3]
]
为了验证数独,我们必须检查所有行、列和子网格
代码解释:
p = a => eval(a.join("*")) == (1*2*3*4*5*6*7*8*9);
这相当于
p = function(a) {
return eval(a.join("*")) == (1*2*3*4*5*6*7*8*9);
}
因此函数 "p" 获取整数数组
[2,4,1,7,6,8,5,3,9]
用“*”连接所有整数,结果我们有:
"2*4*1*7*6*8*5*3*9"
然后评估这个字符串,结果我们有:
362880
这与 1*2*3*4*5*6*7*8*9
的值相同
所以现在我们可以用这个函数检查每一行、每一列和每个子网格。
sudoku = grid =>
grid.every((r,i) =>
validRows &&
validColumns &&
validSubGrids )
等同于:
sudoku = function(grid) {
grid.every( function(r, i) {
return
validRows &&
validColumns &&
validSubGrids
})
}
every
方法为数组中存在的每个元素执行一次提供的回调函数,直到找到一个回调函数 returns 为假值。否则 returns 为真。
有效数独意味着我们的 every
函数对所有元素的回调 returns true
。
p(r)
- 验证每一行
p(grid.map(r => r[i]))
- 验证每一列
函数map
创建新数组。
例如。对于 i=0
它将提供以下结果:
[ grid[0][0], grid[0][1], grid[0][2],...]
p(r.map((_,j) => grid[3*(i/3|0)+(j/3|0)][3*(i%3)+(j%3)]) ) )
- 验证每个子网格
等效代码:
p(
r.map( function(_,j) {
let row = 3 * Math.floor(i/3) + Math.floor(j/3)
let column = 3 * (i%3) + (j%3)
return grid[row][column]
})
)
因此,我们验证了所有行、所有列和所有子网格。
我无法理解使用箭头函数和 .every() 方法的编码挑战的解决方案,希望更有知识的人可以解释发生了什么。挑战在于检查网格以查看它是否代表真正的数独板。我理解第一部分连接和乘以一个 row/col/square,但无法理解后面的部分...
// True, if product of #s in row is 9!
p = a => eval(a.join("*")) == (1*2*3*4*5*6*7*8*9);
// Check each row, column and 3 block grid using p()
sudoku = grid =>
grid.every((r,i) =>
p(r) &&
p(grid.map(r => r[i])) &&
p(r.map((_,j) => grid[3*(i/3|0)+(j/3|0)][3*(i%3)+(j%3)]) ) )
感谢您的帮助!
sudoku = grid =>
grid.every((r,i) =>
p(r) &&
p(grid.map(r => r[i])) &&
p(r.map((_,j) => grid[3*(i/3|0)+(j/3|0)][3*(i%3)+(j%3)]) ) )
- 对于网格中的每个项目 r,计算 p(r)。如果它是真的那么第二部分将被评估
grid.map(r => r[i])
将被评估,这反过来将遍历所有网格项目和 return 它们的 ith 元素的数组.
现在如果p(grid.map(r => r[i]))
为真则后面的部分将被评估。最后
r.map((_,j) => grid[3*(i/3|0)+(j/3|0)][3*(i%3)+(j%3)]) )
将被执行,但前提是前两个条件为真。
这也将 return 一个网格数组项,取决于 i 和 j 的值。
So key points here is the usage of &&
A && B
将 return B 如果 A 的计算结果为真(并且仅当 A 为真时才计算 B)
在大多数情况下,箭头函数只是一个函数。两者之间唯一真正的区别是 this
在使用箭头函数时从外部上下文中保留下来,而 this
是用于使用普通函数调用函数的 this
.
function A() {
this.v = 1;
this.a = () => console.log(this.v);
this.b = function () { console.log(this.v) };
}
// Both will use `obj` as `this`
const obj = new A();
obj.a();
obj.b();
// The arrow-function `a()` will keep the same `this` as above, `obj` will change.
const obj2 = { v: 2 };
obj2.a = obj.a;
obj2.b = obj.b;
obj2.a();
obj2.b();
另一个可能会让你失望的区别是箭头函数,如果它只需要一行,你可以省略大括号 ({}
) 它会 return价值。即,
a => 1
等同于:
function (a) { return 1; }
在此示例代码中,作为箭头函数或常规函数没有区别,因为未调用 this
。
代码的作用是:
grid.every((r, i) =>
查看 grid
中的每个元素,并一直持续到 returns true
。 r
是 grid
的当前值,i
是它正在处理的当前索引。
grid.map(r => r[i])
实际上只是从 r
获取 i-th
值并 returning 它。这将用于检查二维数组的对角线。 (所以它得到 grid[0][0]
、grid[1][1]
,等等)。
r.map((_, j) => grid[math])
然后只是遍历 r
中的每个元素,并使用来自外循环的当前 i
索引和 j
索引获取一些元素(基于该数学)来自 r
。使用 _
作为参数名称是一种常见的约定,表示您不关心该参数。
似乎数独的输入数据是二维数组,如下所示:
let grid = [
[2,4,1,7,6,8,5,3,9],
[5,7,3,9,2,4,1,8,6],
[8,9,6,5,3,1,7,4,2],
[7,3,4,2,9,5,6,1,8],
[1,8,9,4,7,6,3,2,5],
[6,5,2,8,1,3,4,9,7],
[4,6,5,3,8,2,9,7,1],
[3,2,7,1,5,9,8,6,4],
[9,1,8,6,4,7,2,5,3]
]
为了验证数独,我们必须检查所有行、列和子网格
代码解释:
p = a => eval(a.join("*")) == (1*2*3*4*5*6*7*8*9);
这相当于
p = function(a) {
return eval(a.join("*")) == (1*2*3*4*5*6*7*8*9);
}
因此函数 "p" 获取整数数组
[2,4,1,7,6,8,5,3,9]
用“*”连接所有整数,结果我们有:
"2*4*1*7*6*8*5*3*9"
然后评估这个字符串,结果我们有:
362880
这与 1*2*3*4*5*6*7*8*9
所以现在我们可以用这个函数检查每一行、每一列和每个子网格。
sudoku = grid =>
grid.every((r,i) =>
validRows &&
validColumns &&
validSubGrids )
等同于:
sudoku = function(grid) {
grid.every( function(r, i) {
return
validRows &&
validColumns &&
validSubGrids
})
}
every
方法为数组中存在的每个元素执行一次提供的回调函数,直到找到一个回调函数 returns 为假值。否则 returns 为真。
有效数独意味着我们的 every
函数对所有元素的回调 returns true
。
p(r)
- 验证每一行
p(grid.map(r => r[i]))
- 验证每一列
函数map
创建新数组。
例如。对于 i=0
它将提供以下结果:
[ grid[0][0], grid[0][1], grid[0][2],...]
p(r.map((_,j) => grid[3*(i/3|0)+(j/3|0)][3*(i%3)+(j%3)]) ) )
- 验证每个子网格
等效代码:
p(
r.map( function(_,j) {
let row = 3 * Math.floor(i/3) + Math.floor(j/3)
let column = 3 * (i%3) + (j%3)
return grid[row][column]
})
)
因此,我们验证了所有行、所有列和所有子网格。