2015-08-20 2 views
0

Я определил свою собственную функцию карты, которая выполняет ту же задачу, что и метод объектов Array. (Я делаю это, чтобы учиться). Код ниже.Как определить карту с точки зрения ForEach

Я хотел бы использовать метод 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

'array.forEach (преобразование (currentVal, index, array, mapping));' - вы здесь * вызываете * преобразование здесь и передаете его возвращаемое значение (none) в forEach. Возможно, вам понадобится использовать Function.bind, если вы хотите получить доступ к «сопоставленному» внутри цикла без использования закрытия. – Katana314

ответ

0

Отсутствующий понятие здесь проходят по значению. Изменения в аккумуляторе не будут отражаться в forEach. forEach фактически не предназначен для возврата значения для каждой итерации. Для этого у вас есть карта.

Взятые из here,

Foreach перебирает список и применяет некоторые операции с боковыми эффекты для каждого элемента списка (например, сохранение каждого из них в базу данных , например)

карта итерацию над списком преобразует каждый член этого списка, а возвращает другой список того же размера с преобразованными членами (например, преобразование списка строк в верхний регистр)

Попробуйте этот код:

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

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() вызов из главной функции, что означает, что вы должны передать данные вокруг, в то время как мне нужно только ссылки из внешней области. Единственный недостаток моего пути - накладные расходы функции, но это функция стрелки, поэтому она может сделать ее достаточно легкой, чтобы не иметь значения.