如何根据ForEach定义地图

时间:2015-08-20 14:25:48

标签: javascript dictionary foreach

我已经定义了自己的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);
}

2 个答案:

答案 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);
}

JSFiddle - forEach

答案 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函数,这意味着你必须传递数据,而我只需要从外部范围引用。我的方式唯一的缺点是函数的开销,但它是一个箭头函数,所以这可能使它足够轻量级无关紧要。