Комментарии 72
почему я люблю scala
коротко
val filteredHeroes = femaleHeroes.filter( _.sex == "f")
читаемо
def isFemale(x:Heroes) = "f" == x.sex
val filteredHeroes = femaleHeroes.filter(isFemaile)
Так в JS так же:
const filteredHeroes = femaleHeroes.filter(({ sex }) => sex === "f")
const isFemale = ({ sex }) => sex === "f"
const filteredHeroes = femaleHeroes.filter(isFemale)
тогда и там можно найти и упорядоченные списки, и сортировки, и бинарный поиск…
я подумал, может delphi — это слишком притянуто за уши? дополнительно нагуглил freepascal rtl tlist http://www.freepascal.org/docs-html/rtl/classes/tlist.indexof.html
Если без скобок, то в функцию передастся объект. А со скобками сразу произойдет деструктуризация.
Это деструктурирование.
можно написать так
femaleHeroes.filter((hero) => hero.sex === "f")
А можно не писать hero
а достать из него только поле sex, которое нам нужно
femaleHeroes.filter(({ sex }) => sex === "f")
Это какое-то введение в underscore/lodash для самых маленьких.
старый добрый цикл for…of
Улыбнуло :) for...of
, который буквально недавно (в ES6) появился
Например, есть объект:
const modes = {
air: false,
road: true,
sea: false
};
Нужно получить новый объект, в котором будут только те поля, которые в исходном были «true».
Т.е:
const newModes = {
road: true
};
Очень часто такая штука используется в мультиселектах.
const modes = {
air: false,
road: true,
sea: false
};
const newModes = Object.keys(modes)
.filter(key => modes[key])
.reduce((prev, key) => {
return {
...prev,
[key]: modes[key]
}
}, {});
Жаль что в JS нету map/filter/reduce для объектов. Думаю очень удобно было бы иметь что-то типа:
const newModes = modes.filter( (value, key, obj) => value);
или
const newModes = modes.map( (value, key, obj) => ({[key]: !value}));
Можно еще чуть укоротить =)
const newModes = Object.keys(modes)
.reduce((prev, key) => modes[key] ? ({ ...prev, [key]: modes[key] }) : prev, {});
let { road: fieldValue } = modes,
newObj = {
road: fieldValue
};
TLDR:
Работая с массивами старайтесь использовать нативный API (forEach, map, filter, reduce), не делайте код избыточным.
похожи на лежащие на боку буквы «V»Любому программисту знаком оператор ">" :)
Я бы сказал, ни то, ни другое, ни третье. Просто циклы/рекурсия – это низкоуровневая абстракция, которую можно инкапсулировать в отдельной функции, чтобы детали имплементации не смешивались с бизнес-логикой.
Тот же lodash внутри и использует много циклов.
Рекурсивное решение выглядит весьма элегантно. Всего пара строчек кода и минимум отступов. Но рекурсивные реализации алгоритмов обычно используют с большой осторожностью, кроме того, они отличаются плохой производительностью в старых браузерах.
Где тут сказано про выгоду? :)
Про javascript еще всегда интересны статьи на тему «Почему в javascript есть функция eval, откуда она там взялась, зачем она там нужна, и почему такой функции нету в императивных языках вроде Pascal и Java».
Вредная статья, как и каждая вторая про функциональное программирование в JavaScript. Подчеркиваю — в JavaScript.
JavaScript не рассчитан на функциональное программирование, хоть и с виду кажется, что расчитан. Да, есть хай-ордеред функции, да, всякие там лямбды и замыкания. Но если вы пишете [я понимаю, что это перевод, если что], что циклы не нужны, а вот функции нужны, то советую сравнить скорости работы императивного подхода в JS и функционального. Просто возмите и перепишите любой цикл на рекурсию. И сравните. Ведь в функциональных языках, на сколько я знаю, цикл замещается рекурсией? Ну так вот, вы скорее всего расстроетесь и немного загрустите.
Скажем так, против ФП никаких нареканий нет, но оно должно быть уместно и применено в тех языках, которые расчитывают именно на функциональный подход изначально и не являются просто "поддерживаемой парадигмой", а внутренним устройством.
Лично мой подход — это здравое комбинирование императивного и функционального. Функциональное, обычно, описывает архитектуру, какой-то паттерн. А вот конкретные имплементации отдельных функций/методов уже не брезгуют циклами и прочими вещами, далекими от ФП и близкими императивному подходу.
Тем самым сохраняется чистая архитектура и здравая скорость.
Ведь в функциональных языках, на сколько я знаю, цикл замещается рекурсией?Мало знаете, получается. В 95% случаев цикл замещается функцией
map
, reduce
или filter
. Рекурсия в этой роли — это редкий изврат типа факториала, уже для чего-то чуть более сложного типа чисел Фибоначчи цикл просто не подойдёт.Нет, это не так. Map, filter, reduce (а также every и some) мы используем при работе с массивами. Но кроме массивов есть еще какие-то императивные алгоритмы, которые, например, просто должны делать что-то некое количество раз. И не имеют отошения к массивам вообще.
Выполнение некоторой чистой функции несколько раз бессмысленно. Есть близкая абстракция к циклу for — развертка (unfold). Но опять же, это функция, и имеет возвращаемое значение.
Одними чистыми функциями нормальную программу не написать. Хотя есть варианты обходиться без циклов и для "грязных", если в языке есть генераторы или что-то подобное, а то и просто массив создавать, типа (new Array(7)).foreach(...)
Array.apply(0, {length:7}).forEach(...)
Для таких целей существует Array.from
Array.from({length: 7}).forEach(...)
Навскидку написал, по памяти, просто для демонстрации идеи — создать массив нужной длины и пройтись "по нему".
В 95% случаев цикл замещается функцией map, reduce или filter.
При этом map & filter реализуются через reduce, а reduce — через рекурсию )))
Статья эта, туториал, призванный показать применение функций, не так давно интегрированных(ну как минимум, по мнению автора не так давно). Так как всякий туториал, нацелен на тех, для кого его содержание окажется чем-то новым. То с одной стороны, сомнительна необходимость перевода для хабра, с другой, тема не подается к обсуждению.
Тем не менее, она сама по себе цепляет некоторых, и вас в частности. Поэтому для вас утратило значение, что речь в статье сплошь о массивах, другое по сути и не рассматривалось.
И также, шаблон статьи, сначала сделаем плохо, а потом исправим, вовсе не красит и не предлагает реально использовать рекурсию.
Scheme
для скриптования браузера Netscape
по типу AutoCAD
'а, но потом пришли настойчивые маркетологи и сказали что нужен скриптовый язык, похожий на C и Java.Из циклов for и while можно выйти в любой момент. Иногда это нужно.
Вот только лучше уж цикл, чем увидеть такое в продакшн-коде.
function conditionBreak(condition, body){
var state = true;
typeof condition !== 'function' && (condition = function(){});
typeof body !== 'function' && (body = function(){});
return function(){
if (state && condition.apply(undefined, arguments)) {
body.apply(undefined, arguments);
} else {
state = false;
}
}
}
[1, 2, 3, 4, 1, 2, 5].map(conditionBreak((n) => {
return n <= 3;
}, (n) => {
console.log(n);
}));
Лучше уж как-нибудь вот так. В отличии от .filter он не отбирает, а реально "выбрасывает" при первом неудовлетворяющем условии.
Я же написал, чем это отличается от фильтра. Фильтр, если, например, мы имеем массив со значениями 1, 2, 3, 1, 2, 3 и правило выхода "n <= 2", вернет массив со значениями 1, 2, 1, 2.
В вышеописанной функции conditionBreak остановка произойдет после первой тройки, то есть значения будут 1, 2 и все. Это более близко поведению break оператора цикла.
JavaScript без циклов