Найти индекс элемента, соответствующего предикату в Clojure? - PullRequest
24 голосов
/ 27 декабря 2011

С Clojure, как мне найти первый индекс с положительным значением в этом векторе [-1 0 3 7 9]?

Я знаю, что вы можете получить первый результат чего-то довольно элегантно с first и filter:

(first (filter pos? [-1 0 99 100 101]))

Этот код возвращает значение 99.Ответ, который я хочу, - это индекс, который 2.

Ответы [ 6 ]

40 голосов
/ 27 декабря 2011

Используя keep-indexed, вы можете получить последовательность индексов, для которых выполняется предикат:

(defn indices [pred coll]
   (keep-indexed #(when (pred %2) %1) coll))

С помощью этой простой функции вы решите свою проблему с помощью выражения

user=> (first (indices pos? [-1 0 99 100 101]))
2

Обратите внимание, что из-за ленивости keep-indexedindices) не требуется реализовывать всю последовательность, поэтому посторонние вычисления не выполняются.

3 голосов
/ 27 декабря 2011
(defn first-pos [x] 
  (loop [arr x n 0]
     (if (pos? (first arr))
     n
     (recur (next arr) (inc n)))))

Это хороший пример использования мощной хвостовой рекурсии функционального программирования.

1 голос
/ 28 декабря 2011
(first (filter #(not (nil? %)) (map #(when (pos? %1) %2) [-1 1 0 99 100 101] (range))))

Карта может принимать одну или несколько коллекций и возвращать один список, помещать условие на карту и фильтровать ноль.

1 голос
/ 27 декабря 2011
(defn pred-idx [pred [idx hist] cur]
  (if (pred cur)
    [(inc idx) (conj hist idx)]
    [(inc idx) hist]))

(defn idx-filter [pred col]
  (second (reduce (partial pred-idx pred) [0 []] col)))

(first (idx-filter pos? [-1 0 99 100 101]))
2

Не уверен, что это лучше, но это работает. Я думаю, что это требует оценки всей последовательности, и если вам нужны все индексы, это было бы лучше. Правильнее всего, наверное, превратить это в ленивую последовательность, но я готов к вечеру.

0 голосов
/ 03 июля 2018

Я немного опоздал на вечеринку, но предпочитаю:

(defn index-of-pred
  [pred coll]
  (ffirst (filter (comp pred second) (map-indexed list coll))))

;; example usage
(index-of-pred pos? [-1 -2 -5 0 3 4 1 -100])
;=> 4
0 голосов
/ 27 декабря 2011

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

(defn first-index
  ([pred coll] (first-index coll pred 0))
  ([pred coll idx]
    (cond (= coll '()) -1
          (pred (first coll)) idx
          :else (recur pred (rest coll) (inc idx)))))

И используйте это так:

(defn is-pos? [x]
  (> x 0))

(first-index is-pos? [-1 0 3 7 9])

Возвращает нулевой индекс первого элемента, который удовлетворяет предикатупример), или -1, если ни один элемент не соответствует предикату.

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