Как изменить часть вектора в Clojure? - PullRequest
9 голосов
/ 17 августа 2011

Мне интересно, если я упускаю что-то базовое, включая векторную манипуляцию. Допустим, у меня есть следующее:

(def xs [9 10 11 12 13]) 
(def idx [0 2]) 
(def values [1 3])

Если я хочу вернуть вектор [1 10 3 12 13] в Matlab, я бы написал xs(idx) = values. В Clojure есть ли примитивный способ достижения этого? Прямо сейчас я использую следующую функцию:

(defn xinto [seq idx val]
  (apply assoc seq (interleave idx val)))

Спасибо.

Ответы [ 3 ]

8 голосов
/ 17 августа 2011

Это немного неловко, потому что вы разделили idx и values на две последовательности, когда они концептуально отображают индексы в значения.Поэтому, если вы позволите мне немного творчески изменить формат данных:

(def x [9 10 11 12 13]) 
(def changes {0 1, 2 3}) 

(defn xinto [v changes]
  (reduce (fn [acc [k v]]
            (assoc acc k v))
          v
          changes))

(xinto x changes) ;; gets the result you want

Если вы генерируете idx и values каким-то странным образом, что их не удобно группировать вместе, вы можетесгруппируйте их позже с (map list idx values) и затем используйте мою xinto реализацию с этим.

3 голосов
/ 17 августа 2011

Я бы, вероятно, использовал уменьшение для этого:

(reduce 
  (fn [old [i v]] (assoc old i v))
   x   
  (map vector idx values))

Однако, если вы действительно хотите сделать это много (в стиле Matlab), то я бы предложил создать нескольковспомогательные макросы / функции для создания некоторого DSL для векторной манипуляции.

2 голосов
/ 17 августа 2011

Не могу найти что-то лучшее.

В основных функциях последовательности есть replace, но она работает со значениями, а не с ключами. Итак,

(replace {9 2} x)

Вернется

[2 10 11 12 13]

Если вы планируете заниматься математикой в ​​Clojure, я также предлагаю вам взглянуть на Заклинатель . У него много API для манипулирования математическими данными.

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