我已经定义了自己的map函数,它的作用与Array对象上的方法相同。 (我这样做是为了学习)。代码如下。
我想在我自己的map定义中使用Array的forEach方法,但我在概念上缺少一些东西。我怎么能用forEach做到这一点?
不使用forEach工作
// transforming with map
// NOTE: map is already defined in JavaScript
function map(array, transformation) {
var mapped = [];
for (var index in array) {
var currentElement = array[index];
var transformedElement = transformation(currentElement);
mapped.push(transformedElement);
}
return mapped;
}
我尝试使用forEach
function mapForEach(array, transformation) {
var mapped = [];
array.forEach(transformation(currentVal, index, array, mapped));
return mapped;
}
function transformation(person, index, array, accumulator) {
var name = person.name;
accumulator.push(name);
}
答案 0 :(得分:0)
这里缺少的概念是按值传递。累加器的更改不会反映在forEach中。 forEach实际上并不是为每次迭代返回一个值。为此你有地图。
取自here,
foreach遍历列表并应用side的一些操作 对每个列表成员的影响(例如将每个列表成员保存到数据库中) 例如)
map迭代列表,转换该列表的每个成员,然后 返回与转换成员相同大小的另一个列表 (例如将字符串列表转换为大写)
试试这段代码:
function mapForEach(array, transformation) {
var mapped = array.map(transformation);
return mapped;
}
function transformation(person, index, array) {
var name = person.name;
return name;
}
这是JSFiddle
如果您必须使用forEach,则必须使用全局变量而不是传递值。那就是
var accumulator =[];
function mapForEach(array, transformation) {
array.forEach(transformation);
return accumulator;
}
function transformation(person, index, array) {
var name = person.name;
accumulator.push(name);
}
答案 1 :(得分:0)
你的方法几乎是正确的,但就像@Katana314所说,你需要绑定,而不是打电话。
以下是我将如何做到这一点:
function map(array,mapper) {
var ret=[];
array.forEach((val,key)=>{
//Since arrays are supposed to be sequential, we don't have to worry
//about keys matching, if they don't match, the user/developer did
//something horribly wrong.
ret.push(mapper(val,key,array));
});
return ret;
}
以下是我如何解决问题的方法。
function mapForEach(array, func) {
var mapped = [];
array.forEach(mapForEachPusher.bind(null,mapped,func));
return mapped;
}
function mapForEachPusher(mapped,func,value,index,array) {
mapped.push(func(value,index,array));
}
function extract_name(person) {
return person.name;
}
mapForEach(
[{name:'Billy'},{name:'Bob'},{name:'Bridget'},{name:'Brittany'},{name:'"B word"'}]
,extract_name
);
//["Billy", "Bob", "Bridget", "Brittany", "\"B word\""]
它实际上是一样的,你的方式将.push()
调用移出main函数,这意味着你必须传递数据,而我只需要从外部范围引用。我的方式唯一的缺点是函数的开销,但它是一个箭头函数,所以这可能使它足够轻量级无关紧要。