在Clojure中:为什么无法在此上下文中解析符号:hdcit

时间:2016-01-09 01:11:52

标签: clojure

我尝试在nums[i]+nums[j]==target

列表中解决查找两个数字索引
(defn two-sum [nums target]
  "Find sum of two numbers equals to target"
  (if (<= 1 (count nums))
    nil)
  (let [hdict (hash-map)]
    (for [i (range 1 (count nums))]
      (if (get hdict (nums i))
        [(get hdict (nums i)) i]        ;return hdict[nums[i]] and i
        (assoc hdcit (- target (nums i)) i)))))

我收到了这个错误:

1. Caused by java.lang.RuntimeException
   Unable to resolve symbol: hdcit in this context

我很困惑:我已经将hdict绑定为hash-map,为什么还无法解决?

1 个答案:

答案 0 :(得分:2)

错误是一个简单的错字,尽管还有其他几点值得考虑:

  • Clojure if表达式总是返回一个值,如果你没有指定else子句(第二个表达式),那么它默认为nil

所以上面代码中的if基本上是这样说的:

 (if contition 
   nil ;; the true case
   nil ;; the false case)

始终返回零。虽然因为它不是函数中的最后一个表达式,但是这个值将被忽略,因为:

  • 函数的返回值(以及大多数其他表达式)是表达式中的最后一个值。

您很可能希望将)移到nil之后到函数末尾。

  • Clojure数据结构是不可变的,在地图上调用assoc会生成新地图,该地图具有附加值,同时保持旧版本不变,因为其他人可能正在处理它。< / LI>

所以最后一行的assoc永远不会做任何事情。

  • for不是“for循环”,而是根据非常强大的表达式“迷你语言”(DSL)懒惰地生成一系列新值

这意味着它只在读取时产生一个值。因此,除非打印值,否则此for循环将不会运行。 REPL将打印此功能并使此功能仅在开发中工作。我称之为“懒惰的虫子”。

不可变数据是Clojure的核心概念,基本上所有语言的优点都至少部分来自于它。

<小时/> Clojure的 for表达式足以完全解决此问题:

user> (let [data [1 2 3 4 5 6 7 42 12]
            target 12]
        (for [x data
              y data
              :when (= (+ x y) target)]
          [x y]))
([5 7] [6 6] [7 5])