如何从 arr.map(elem => dict[elem]) 中提取函数?
How to extract a function out of arr.map(elem => dict[elem])?
一个函数应该只做一件事 被认为是编写函数时的一个好习惯。然而,我有一个已经非常小的功能,但是我认为它可以进一步提取,但我不知道如何做到这一点。
以下 recode()
函数根据查找字典替换数组值。
function recode(arr, dict) {
return arr.map(elem => dict[elem])
}
工作原理示例:
// input data to be recoded
const myArr = ['eggplant', 'tomato', 'carrot', 'cabbage'];
// look-up dictionary
const myDict = {
eggplant: 'purple',
tomato: 'red',
carrot: 'orange',
};
const result1 = recode(myArr, myDict)
console.log(result1) // => ["purple", "red", "orange", undefined]
在我看来,当前的 recode()
函数做了两件事:
- 它按身份匹配(您可能有比这更好的描述),即
elem => dict[elem]
;和
- 它映射到
arr
我的问题是我是否可以为 elem => dict[elem]
提取一个单独的函数,并将该函数提供给 arr.map()
。我想象的是:
// pseudo-code
function funcInner() {...}
function recode(arr, dict) {
return arr.map(funcInner)
}
这样,我将拥有一个仅执行替换的功能,而另一个仅映射 arr
。
编辑
针对评论,我想打个比方。让我们考虑一个将数组值加倍的函数。
function doubleArray(arr) {
return arr.map(x => x * 2)
}
这里有些人可能会说 doubleArray()
已经在做一件事了。但是,我们仍然可以提取:
const doubleNumber = x => x * 2;
function doubleArray2(arr) {
return arr.map(doubleNumber)
}
据我了解,doubleArray()
做了两件事(double & map),而 doubleArray2()
只做了一件事(map)而 doubleNumber()
做了一件事(doubles) .因此,doubleArray()
并不是无意义的重构。
此外,一旦我们有了一个只做一件事的函数,它就会促进我们可以为它编写更准确的单元测试。
最后,如果我们将这段代码翻译成 typescript(我在这个问题中没有关注),那么 doubleNumber()
中的输入类型与doubleArray()
中的输入类型。所以这是我更喜欢提取的另一个原因。
我是 javascript 的新手,但这是我的理解方式。所以我关于 recode()
的问题就是在这种情况下。
在你的情况下你不需要提取,这就是箭头函数存在的原因。
回答你的问题:
function recode(arr, dict) {
return arr.map(elem => funcInner(elem,dict));
};
function funcInner(elem, dict) {
return dict[elem];
}
但我同意其他人对你问题的评论,这可能有点矫枉过正。您的选择。
本质上 recode
被用作 arr.map()
. This could also be achieved by assigning recode
to a function returned by calling the Function.bind()
method 的包装器。
const recode = myArr.map.bind(myArr, elem => myDict[elem]);
myArr
需要作为第一个参数传入,绑定数组上下文
// input data to be recoded
const myArr = ['eggplant', 'tomato', 'carrot', 'cabbage'];
// look-up dictionary
const myDict = {
eggplant: 'purple',
tomato: 'red',
carrot: 'orange',
};
const recode = myArr.map.bind(myArr, elem => myDict[elem]);
const result1 = recode(myArr, myDict)
console.log(result1) // => ["purple", "red", "orange", undefined]
但也许直接调用 .map()
更简单:
// input data to be recoded
const myArr = ['eggplant', 'tomato', 'carrot', 'cabbage'];
// look-up dictionary
const myDict = {
eggplant: 'purple',
tomato: 'red',
carrot: 'orange',
};
const result1 = myArr.map(elem => myDict[elem])
console.log(result1) // => ["purple", "red", "orange", undefined]
如果希望有一个user-supplied回调,那么可以使用ES-6 default parameters:
function recode(myArr, myDict, callback = elem => myDict[elem]) {
return myArr.map(callback);
}
// input data to be recoded
const myArr = ['eggplant', 'tomato', 'carrot', 'cabbage'];
// look-up dictionary
const myDict = {
eggplant: 'purple',
tomato: 'red',
carrot: 'orange',
};
const result1 = recode(myArr, myDict)
console.log(result1) // => ["purple", "red", "orange", undefined]
const result2 = recode(myArr, myDict, elem => myDict[elem] + 'a')
console.log(result2) // => ["purplea", "reda", "orangea", "undefineda"]
的细微变化:让另一个函数 return 可以用作 Array#map
的回调函数:
function createMapper(dict) {
return elem => dict[elem];
}
function recode(arr, dict) {
return arr.map(createMapper(dict));
}
但我也会质疑这是否真的是对您原始代码的改进。
一个函数应该只做一件事 被认为是编写函数时的一个好习惯。然而,我有一个已经非常小的功能,但是我认为它可以进一步提取,但我不知道如何做到这一点。
以下 recode()
函数根据查找字典替换数组值。
function recode(arr, dict) {
return arr.map(elem => dict[elem])
}
工作原理示例:
// input data to be recoded
const myArr = ['eggplant', 'tomato', 'carrot', 'cabbage'];
// look-up dictionary
const myDict = {
eggplant: 'purple',
tomato: 'red',
carrot: 'orange',
};
const result1 = recode(myArr, myDict)
console.log(result1) // => ["purple", "red", "orange", undefined]
在我看来,当前的 recode()
函数做了两件事:
- 它按身份匹配(您可能有比这更好的描述),即
elem => dict[elem]
;和 - 它映射到
arr
我的问题是我是否可以为 elem => dict[elem]
提取一个单独的函数,并将该函数提供给 arr.map()
。我想象的是:
// pseudo-code
function funcInner() {...}
function recode(arr, dict) {
return arr.map(funcInner)
}
这样,我将拥有一个仅执行替换的功能,而另一个仅映射 arr
。
编辑
针对评论,我想打个比方。让我们考虑一个将数组值加倍的函数。
function doubleArray(arr) {
return arr.map(x => x * 2)
}
这里有些人可能会说 doubleArray()
已经在做一件事了。但是,我们仍然可以提取:
const doubleNumber = x => x * 2;
function doubleArray2(arr) {
return arr.map(doubleNumber)
}
据我了解,doubleArray()
做了两件事(double & map),而 doubleArray2()
只做了一件事(map)而 doubleNumber()
做了一件事(doubles) .因此,doubleArray()
并不是无意义的重构。
此外,一旦我们有了一个只做一件事的函数,它就会促进我们可以为它编写更准确的单元测试。
最后,如果我们将这段代码翻译成 typescript(我在这个问题中没有关注),那么 doubleNumber()
中的输入类型与doubleArray()
中的输入类型。所以这是我更喜欢提取的另一个原因。
我是 javascript 的新手,但这是我的理解方式。所以我关于 recode()
的问题就是在这种情况下。
在你的情况下你不需要提取,这就是箭头函数存在的原因。
回答你的问题:
function recode(arr, dict) {
return arr.map(elem => funcInner(elem,dict));
};
function funcInner(elem, dict) {
return dict[elem];
}
但我同意其他人对你问题的评论,这可能有点矫枉过正。您的选择。
本质上 recode
被用作 arr.map()
. This could also be achieved by assigning recode
to a function returned by calling the Function.bind()
method 的包装器。
const recode = myArr.map.bind(myArr, elem => myDict[elem]);
myArr
需要作为第一个参数传入,绑定数组上下文
// input data to be recoded
const myArr = ['eggplant', 'tomato', 'carrot', 'cabbage'];
// look-up dictionary
const myDict = {
eggplant: 'purple',
tomato: 'red',
carrot: 'orange',
};
const recode = myArr.map.bind(myArr, elem => myDict[elem]);
const result1 = recode(myArr, myDict)
console.log(result1) // => ["purple", "red", "orange", undefined]
但也许直接调用 .map()
更简单:
// input data to be recoded
const myArr = ['eggplant', 'tomato', 'carrot', 'cabbage'];
// look-up dictionary
const myDict = {
eggplant: 'purple',
tomato: 'red',
carrot: 'orange',
};
const result1 = myArr.map(elem => myDict[elem])
console.log(result1) // => ["purple", "red", "orange", undefined]
如果希望有一个user-supplied回调,那么可以使用ES-6 default parameters:
function recode(myArr, myDict, callback = elem => myDict[elem]) {
return myArr.map(callback);
}
// input data to be recoded
const myArr = ['eggplant', 'tomato', 'carrot', 'cabbage'];
// look-up dictionary
const myDict = {
eggplant: 'purple',
tomato: 'red',
carrot: 'orange',
};
const result1 = recode(myArr, myDict)
console.log(result1) // => ["purple", "red", "orange", undefined]
const result2 = recode(myArr, myDict, elem => myDict[elem] + 'a')
console.log(result2) // => ["purplea", "reda", "orangea", "undefineda"]
Array#map
的回调函数:
function createMapper(dict) {
return elem => dict[elem];
}
function recode(arr, dict) {
return arr.map(createMapper(dict));
}
但我也会质疑这是否真的是对您原始代码的改进。