получение границ списка точек x, y - PullRequest
5 голосов
/ 06 июля 2011

У меня есть список точек x, y, сохраненных как вектор векторов, и я хочу узнать границы.

Например, с учетом этого:

[[0 0] [20 30] [-50 -70] [200 300]]
* 1005результат будет:
{:x -50, :y -70, :x2 200, :y2 300}

Вот что у меня так далеко.Это дает желаемый результат, но мне кажется многословным и не очень замкнутым.

(defn get-stroke-bounds [vector-of-points]
  (reduce (fn [m [x y]]
        {:x  (min (:x  m Integer/MAX_VALUE) x)
         :y  (min (:y  m Integer/MAX_VALUE) y)
         :x2 (max (:x2 m Integer/MIN_VALUE) x)
         :y2 (max (:y2 m Integer/MIN_VALUE) y)})
      {}
      (vector-of-points)))

Есть идеи, как его улучшить?Спасибо!

Ответы [ 3 ]

4 голосов
/ 06 июля 2011

Ваше решение уже довольно хорошее!Это довольно идиоматично, а также O (n) по количеству точек, что является алгоритмически оптимальным (на самом деле лучше, чем метод, выполняющий сортировку).

Но вот альтернативный способ сделать это, вы можете найти интересным.... создано главным образом потому, что я большой поклонник функций высшего порядка: -)

(defn get-stroke-bounds [stroke]
     (zipmap
       [:x :y :x2 :y2]
       (map
         (fn [[getter reducer]]
           (reduce 
             reducer
             (map getter stroke)))
         [
          [first min]
          [second min]
          [first max]
          [second max]])))
3 голосов
/ 07 июля 2011

Если я уже использую векторы для входных точек, я бы хотел, чтобы возвращаемое значение было в том же формате.Имея это в виду, я думаю, что это хорошее идиоматическое решение:

(defn bounds
  [points]
  (let [xs (sort (map first points))
        ys (sort (map second points))]
    (list [(first xs) (first ys)]
          [(last xs) (last ys)])))
1 голос
/ 06 июля 2011

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

(let [v [[0 0] [20 30] [-50 -70] [200 300]]
      v-sorted (apply sorted-set v)]
  [(first v-sorted) (last v-sorted)])

Обновление : извините, вышеприведенный код неверен. Необходимо отсортировать отдельно x и y, чтобы найти границу, а не точки max или min. решение Джона лучше, если наборы не являются предпочтительными.

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