Clojure中的Python setdefault函数

时间:2018-06-17 19:11:33

标签: clojure

我想在Clojure中做类似的事情:

#增加功能/类别对的数量

  def incf(self,f,cat):    
    self.fc.setdefault(f,{})    
    self.fc[f].setdefault(cat,0)    
    self.fc[f][cat]+=1

有人有想法吗?

2 个答案:

答案 0 :(得分:8)

我认为一个接近的并行是fnil,它接受​​一个函数和一些默认参数值,然后返回一个函数,如果用nil参数调用它将使用默认值:

(defn incf [fc f cat]
  (update-in fc [f cat] (fnil inc 0)))

(incf {} :feature-foo :category-bar)
=> {:feature-foo {:category-bar 1}}

这里我们使用update-in来更新输入映射中的嵌套值,并使用fnil将默认值设置为零,如果它不存在则递增。

答案 1 :(得分:2)

首先,你不能在Clojure中改变哈希映射,因此setdefault没有确切的对应物。

但是,如果要更新嵌套映射以增加给定值(或设置为1,如果它为null),则可以利用clojure.core/get可以接受可选第三个参数的事实,这是默认值价值(以及assoc上的nil创建地图):

(defn incf [m cat f]
  (let [val (get-in m [cat f] 0)]
    (assoc-in m [cat f] (inc val))))

(incf {:my-cat {:a 1}} :my-cat :a) ; returns {:my-cat {:a 2}}
(incf {:my-cat {}} :my-cat :a)     ; returns {:my-cat {:a 1}}
(incf {} :my-cat :a)               ; returns {:my-cat {:a 1}}