替换Clojure向量中的重复项

时间:2017-10-21 17:34:20

标签: vector clojure

我正在尝试用空字符串替换向量中的重复项。但是,我能找到的唯一功能是删除重复项,而不是替换它们。我怎么能

["Oct 2016" "Oct 2016" "Nov 2016" "Nov 2016" "Nov 2016" "Nov 2016"]

并输出:

["Oct 2016" "" "Nov 2016" "" "" ""]

我能找到的所有内容都会返回["Oct 2016" "Nov 2016"]我目前通过嵌套doseq实现所需的输出,但效果似乎不高。有没有更好的方法来实现这一目标? 谢谢!

5 个答案:

答案 0 :(得分:5)

这是解决方案的策略。

  1. public class AccountControllerTest { //AccountController accountController; public AccountController Setup() { var userStoreMock = new Mock<IUserStore<UserEntity>>(); var mockUserMgr = new Mock<UserManager<UserEntity>>(userStoreMock.Object, null, null, null, null, null, null, null, null ); mockUserMgr.Setup(mgr => mgr.CreateAsync(It.IsAny<UserEntity>())).Returns(Task.FromResult(IdentityResult.Success)); mockUserMgr.Setup(mgr => mgr.ChangePasswordAsync(It.IsAny<UserEntity>(), It.IsAny<string>(), It.IsAny<string>())) .Returns(Task.FromResult(IdentityResult.Success)); mockUserMgr.Setup(mgr => mgr.FindByNameAsync(It.IsAny<string>())) .Returns(Task.FromResult(new UserEntity { UserName = "nityaprakash@gmail.com" })); var roleStoreMock = new Mock<IRoleStore<KanbanRoles>>(); var mockRoleMgr = new Mock<RoleManager<KanbanRoles>>( roleStoreMock.Object, null, null, null, null); return new AccountController(mockUserMgr.Object, mockRoleMgr.Object); } [Fact] public async Task Change_Password_Negative_Test() { Thread.CurrentPrincipal = new GenericPrincipal( new GenericIdentity("nityaprakash@gmail.com"), new[] {"NormalUser"} ); AccountController accountController = Setup(); ChangePasswordModel model = new ChangePasswordModel { CurrentPassword = "currentPassowrd", ConfirmPassword = "NewPassword", NewPassword = "NewPassword" }; var result = await accountController.ChangePassword(model); KanbanResult kResult = Assert.IsType<KanbanResult>(result); Assert.Equal("Error", kResult.Status); } } 关于向量的项目。
  2. 维护loop个已访问的项目。它可用于检查唯一性。
  3. 对于每个项目:如果集合包含当前项目,则将set插入结果向量中。
  4. 如果当前项目是唯一的,则将其插入结果向量和集合中。
  5. 访问所有项目时返回结果向量。
  6. 可选:使用transient结果向量以获得更好的效果。
  7. 代码:

    ""

    致电:

    (defn duplicate->empty [xs]
      (loop [xs     (seq xs)
             result []
             found #{}]
            (if-let [[x & xs] (seq xs)]
              (if (contains? found x)
                (recur xs (conj result "") found)
                (recur xs (conj result x) (conj found x)))
              result)))
    

答案 1 :(得分:2)

传感器版本只是为了完整性。

(defn empty-duplicates
  ([]
   (fn [rf]
     (let [seen (volatile! #{})]
       (fn
         ([] (rf))
         ([res] (rf res))
         ([res x]
          (if (contains? @seen x)
            (rf res "")
            (do (vswap! seen conj x)
                (rf res x))))))))
  ([coll]
   (sequence (empty-duplicates) coll)))

(comment

  (def months ["Oct 2016" "Oct 2016" "Nov 2016" "Nov 2016" "Nov 2016" "Nov 2016"])

  (into [] (empty-duplicates) months) ;=> ["Oct 2016" "" "Nov 2016" "" "" ""]

  )

答案 2 :(得分:1)

(defn eliminate-duplicates [v]
        (let [result (transient (vec (repeat (count v) "")))
              index-of-first-occurences (apply merge-with #(first %&) (map-indexed (fn [x y] {y x}) v))]
            (doall (for [[s pos] index-of-first-occurences]
                       (assoc! result pos s)))
            (persistent! result)))

答案 3 :(得分:1)

与上面基本相同,但使用延迟序列生成:

(defn rdups
  ([items] (rdups #{} items))
  ([found [x & xs :as items]]
   (when (seq items)
     (if (contains? found x)
       (lazy-seq (cons "" (rdups found xs)))
       (lazy-seq (cons x (rdups (conj found x) xs)))))))

user> (rdups ["Oct 2016" "Oct 2016" "Nov 2016" "Nov 2016" "Nov 2016" "Nov 2016"])
;;=> ("Oct 2016" "" "Nov 2016" "" "" "")

答案 4 :(得分:0)

您可以使用iterate

(def months ["Oct 2016" "Oct 2016" "Nov 2016" "Nov 2016" "Nov 2016" "Nov 2016"])

(defn step [[[head & tail] dups res]]
  [tail
   (conj dups head)
   (conj res (if (dups head)
               ""
               head))])

(defn empty-dups [xs]
  (->> (iterate step [xs #{} []])
       (drop-while (fn [[[head] _ _]] head))
       (map #(nth % 2))
       first))

(empty-dups months)
;; => ["Oct 2016" "" "Nov 2016" "" "" ""]