Как я могу перебирать элементы из двух разных списков в Clojure в lockstep? - PullRequest
0 голосов
/ 09 июля 2019

У меня есть два списка в clojure a и b, которые имеют одинаковую длину. Я хочу сделать следующее


for i in range(len(a)):
    if a[i] == b[i]:
        do_something(a[i], b[i])

То, что я пробовал, но не сработало. for не перебирает соответствующие элементы, но все возможные комбинации:


(for [i a j b] (do-something i j))

Ответы [ 3 ]

2 голосов
/ 09 июля 2019

Идиоматический эквивалент может быть:

(doall (map do-something a b))

... или, как расширенная версия того, что вы все еще пишете свой собственный цикл:

(doseq [[i j] (map vector a b)]
  (do-something i j))
  • Поскольку for является ленивым, он может на самом деле не оценить всю вашу последовательность, если что-то не потребляет ее результат;doseq всегда вызывает do-something для всего.
  • map somefunc arg1 arg2 вызывает somefunc с каждым набором значений в arg1 и arg2, именно то, что вы ищете здесь.

Более прямой перевод может выглядеть так:

(doseq [i (range (count a))]
  (do-something (nth a i) (nth b i)))

... но не используйте его;count и nth могут быть медленными или недоступными, в зависимости от используемых типов коллекции.

1 голос
/ 09 июля 2019

Добавьте условие "if" в цикл:

(doseq [[x y] (map vector a b)
        :when (= x y)]
 (do_something x y))
0 голосов
/ 12 июля 2019

Если вы хотите использовать вспомогательную функцию, У меня уже есть одна , которая делает это:

(ns tst.demo.core
  (:use tupelo.test)
  (:require [tupelo.core :as t]))

  (let [xs [ 1  2  3]
        ys [10 20 30]]
    (is= [11 22 33]
      (t/map-let [x xs
                  y ys]
        (+ x y))))

Итак, вы пишете привязки в x и y какформа let, но затем она работает с локальными «переменными», как если бы она была mapv.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...