Clojure 有没有更好的方法从已排序的地图中分解头部或尾部范围?

Clojure 有没有更好的方法从已排序的地图中分解头部或尾部范围?,clojure,Clojure,在Java中,使用Java.util.SortedMap,我们可以执行以下操作: sortedMap.headSet(13).clear() 删除所有键小于13的元素。对于clojure的(排序映射)(我认为总是clojure.lang.PersistentTreeMap),我在clojure.core中没有看到任何类似的内容。我想到的最好的办法是: (let [clear-up-to 13 sm (sorted-map 1 "aye" 2 "bee" 13 "em" 14 "en

在Java中,使用
Java.util.SortedMap
,我们可以执行以下操作:

sortedMap.headSet(13).clear()
删除所有键小于13的元素。对于clojure的
(排序映射)
(我认为总是
clojure.lang.PersistentTreeMap
),我在clojure.core中没有看到任何类似的内容。我想到的最好的办法是:

(let [clear-up-to 13
      sm (sorted-map 1 "aye" 2 "bee" 13 "em" 14 "en")]
      clear-keys (take-while #(< % clear-up-to) (keys sm))
  (apply dissoc sm clear-keys))
(让[清除到13
sm(分类地图1“是”2“蜜蜂”13“em”14“en”)]
清除键(需要一段时间(<%清除到)(键sm))
(应用dissoc sm清除键)

我错过了更简单的东西吗?

我认为对于内置的排序映射,通常没有更有效的解决方案,尽管在许多情况下使用java.util.SortedMap是完全合理的。尤其是当你在切碎它之后把它变成一个持久的贴图

为了实现其价值,还可以使用
reduce

user> my-sorted-map
{2 1, 4 3, 6 5, 8 7}

user>  (reduce dissoc my-sorted-map (take-while #(< % 5) (keys my-sorted-map)))
{6 5, 8 7}
user>mysortedmap
{2 1, 4 3, 6 5, 8 7}
用户>(减少dissoc我的已排序地图(使用while(<%5)(为我的已排序地图设置关键帧)))
{6 5, 8 7}

虽然这主要是口味的问题。你的例子也很好

Dissoc是您所能做的最好的方法,但是
take while
步骤应酌情替换为
subseq
rsubseq

Clojure数据结构是不可变的,因此您的方法是正确的。即使有内置的核心函数,它也会使用类似的方法。同意的
(apply dissoc sm(map key(subseq sm<13))
更干净。我还没有检查persistentreemap是否优化了它,但我更喜欢使用多个键一次性调用dissoc,所以不必创建所有这些中间映射。