Помните, в прошлом посте я говорил, как я хотел бы углубиться в различия векторов и списков? Помимо производительности и того, как растут эти структуры данных (списки в начале, векторы в конце), вероятно, нет необходимости углубляться в кроличью нору. Поверьте мне, это и глубоко, и темно.
Seq или последовательность в Clojure — это просто еще одна структура данных, которая выглядит и работает во многом как списки. Затем мы можем запускать для этих последовательностей невероятно мощные функции, называемые функциями seq. Эти списки функций аналогичны перечислениям в Ruby или использованию библиотеки lodash в JavaScript.
Давайте взглянем на один из них, создав функцию построения уверенности.
user=> (defn confidence-builder [name affirmations] (map #(str name " is " %"!" ) affirmations)) user=> (confidence-builder “Robert” ‘(“cool” “fun” “smart”)) (“Robert is cool!” “Robert is fun!” “Robert is smart!”)
Спасибо строитель уверенности, я умный, крутой и веселый!
Функция принимает два аргумента, имя и список утверждений. map – это функция seq, которая позволяет запускать функцию для каждого значения в списке в последовательном порядке.
Здесь мы передаем список утверждений, начиная с первого, и запускаем для него функцию str. Помните, что последовательность очень похожа на список, мы начинаем с первого значения, а затем переходим к следующему, пока не дойдем до конца.
Векторы не являются последовательностями, но вы можете запускать на них функции последовательности.
user=> (seq? ‘(1 2 3)) true user=> (seq? [1 2 3]) false (confidence-builder “Robert” [“cool” “fun” “smart”]) (“Robert is cool!” “Robert is fun!” “Robert is smart!”)
Для вектора мы вызываем функцию seq?, которая говорит нам, является ли что-то последовательностью или нет. Мы получаем обратно false, но все же карта функции seq все еще работает с вектором, когда мы вызываем нашу функцию построения уверенности. Что дает?
любая функция seq, такая как map, filter или reduce, сначала попытается вызвать seq для этого типа данных, прежде чем запускать функцию seq. Проверь это
user=> (seq [“cool” “fun” “smart”]) (“cool” “fun” “smart”) user=> (seq {:a “apple” :b “banana”}) ([:a “apple”] [:b “banana”])
Круто, это работает для векторов и карт. Поэкспериментируйте с различными функциями seq, которые вы можете найти здесь, и обрушьте их могучую силу на ничего не подозревающие векторы, карты и списки!