map
Давайте рассмотрим еще одну функцию, которая есть в Javascript.
var names = [];
for( var i =0, l= tweeps.length, i< l; ++i){
names.push(tweeps[i].name);
}
Это абстракция, которая соответствует трансформации списка.
Используя map мы можем решить эту задачу гораздо проще
//Array.prototype.map
var names = tweeps.map(function (tweep){
return tweep.name;
});
Мы избавились от временных переменных, от описания цикла. Прямое и понятный код. И поскольку функция обработки достаточно короткая, мы можем уместить все в одну строку.
var names = tweeps.map(function(t){return t.name;});
Я не фанатик записи кода в одну строку. Но то, сколько идей можно выразить одной строкой говорит о выразительности вашего API.
Теперь поищем упоминания в твиттере.
var str = "mentioned by";
for(var i =0; l= tweeps.length; i < l; ++i){
str += tweeps[i].name;
if(i< tweeps.length-1) {str += ", "}
}
Достаточно корявый пример. Тут может быть куча ошибок с индексацией и получением элемента массива.
Давайте проанализируем, что мы реально делаем в этом примере:
- Вытаскиваем имена пользователей
- Объединяем имена пользователей (при этом в конце списка не должно быть запятой)
- Используем запятую в качестве разделителя
Перепишем, используя map и join
var str = "mentioned by " + tweeps.map(function(t){
return t.name;
}).join(", ");
Возможностей ошибиться стало гораздо меньше.
Но можно ли сделать лучше? :)
Давайте введем еще одну функцию высшего порядка, которую будем использовать для доступа к свойствам объектов.
Назовем ее prop
function prop(name){
return function (object){
return object[name];
}
}
На первый взгляд она достаточно бессмысленна. Мы передаем в нее имя,
а она возвращает нам функцию, куда передается объект из которого вытаскиваем необходимое поле.
Какое-то запутанное объяснение получилось. Давайте просто попробуем использовать эту фукнцию на реальной задаче.
var str = "Mentioned by " + tweeps.map(prop ("name")).join(", ");
Итак, еще один однострочник. Достаточно неплохая выразительность. А функция prop не так уж бесполезна.