Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
转换为clojure线程运算符_Clojure - Fatal编程技术网

转换为clojure线程运算符

转换为clojure线程运算符,clojure,Clojure,我在一个let中有以下代码 ;租赁条款 课程完整(进入[] (地图#)(dissoc(合并%(第一课详细%)) :id:series\u id:lesson\u id:num) (课程) 奇怪的是,我偶然使用了传感器形式,在错误的地方得到了一个paren。这是上面显示的版本。为便于比较,不带传感器的版本为: ;租赁条款 课程完整(进入[] (地图#)(dissoc(合并%(第一课详细%)) :id:series\u id:lesson\u id:num) (课程) 这同样有效 在这个转换中,

我在一个let中有以下代码

;租赁条款
课程完整(进入[]
(地图#)(dissoc(合并%(第一课详细%))
:id:series\u id:lesson\u id:num)
(课程)
奇怪的是,我偶然使用了传感器形式,在错误的地方得到了一个paren。这是上面显示的版本。为便于比较,不带传感器的版本为:

;租赁条款
课程完整(进入[]
(地图#)(dissoc(合并%(第一课详细%))
:id:series\u id:lesson\u id:num)
(课程)
这同样有效

在这个转换中,我还有几件事要做,包括转换一个名为
:type
的键的值,该键当前是一个字符串,带有
关键字
。然而,这正成为高认知负荷。 尚未熟练掌握穿线操作员。是否有人可以帮助您完成这方面的第一步/思考过程

课程
是来自jdbc查询的映射列表


更新:草稿答案-转换为线程最后一个运算符的思考过程

步骤1

准备玩杂耍。1.从最后一个线程开始
->
,2。把论点,
lessons
放在前面,3。将最后的变换
放在末尾的
中。此版本有效,但我们尚未完成:

;租赁条款
课程已满(->>课程
(地图#)(dissoc(合并%(第一课详细%))
:id:series\u id:lesson\u id:num),,,)
(进入[],,))
请注意,
、、
被clojure忽略,我们添加它们是为了帮助可视化线程last
->
宏在何处注入参数

步骤2

我们拉出
dissoc
,但是由于我们在调用
map
时使用了它,所以当我们拉出它时,我们需要在另一个调用
map
时将其包装起来

;租赁条款
课程已满(->>课程
(地图#(合并%(第一课细节%),,,)
(映射#(dissoc%:id:series_id:lesson_id:num),,,,)
(进入[],,))
这也行。让它沉下去


更新2

最后,以下是实现我最初目标的代码:

;租赁条款
课程已满(->>课程
(地图#(合并%(课程细节%),,,)
(映射#(dissoc%:id:series_id:lesson_id:num),,,,)
(地图#(关联%:类型(关键字(:类型%)),,,)
(进入[],,))

除非我弄错了,否则在线程最后一个宏内部似乎不容易使用。另外,我在地图上画了三次。在我当前的用例中,这可能无关紧要,但这里是否有关于性能或任何其他可能的改进的建议?

如果您建议的代码认知负载是这里的问题,您可以将您在每节课上所做的操作分解为其自身的功能,例如:

(defn preprocess-lesson [lesson]
  (dissoc (merge lesson (first (lesson-detail lesson)))
          :id :series_id :lesson_id :num))
这有几个好处:

  • 您可以为
    预处理课程
  • 很明显,这个预处理课程的操作只需要一个
    课程
    作为参数,而不依赖于周围范围中的某个值
  • 课程顺序上的转换看起来更清晰
如果要使用线程操作符,可以编写

(->> lessons
     (map preprocess-lesson))
(into []  (map preprocess-lesson) lessons)
如果你想使用传感器,你可以写

(->> lessons
     (map preprocess-lesson))
(into []  (map preprocess-lesson) lessons)
假设您想在课程中执行更多操作,您甚至可以在
预处理课程中使用threading操作符:

(defn preprocess-lesson [lesson common-lesson-data]
  (-> lesson
      (merge (first (lesson-detail lesson)))
      (dissoc :id :series_id :lesson_id :num)
      (assoc :type (get lesson "type"))
      (dissoc "type")
      (merge common-lesson-data)))
然后像这样称呼它

(->> lessons
     (map #(preprocess-lesson % {:teacher "Rudolf"})))
尚未熟练掌握穿线操作员。有人能帮忙吗 第一步/思考过程

线程宏通过澄清计算中的数据流,使代码更具可读性。而不是写作

(filter a? (map b (filter c? X)))
你可以写

(->> X
     (filter c?)
     (map b)
     (filter a?))

这可能更具可读性,也可能更容易理解其意图。但除此之外,它们并没有在嵌套表达式上添加任何额外的表达能力,比如
(filter a?(map b(filter c?X))
。简而言之,使用线程宏是为了使代码更具可读性,而不是为了使用它们。如果在一个单独的函数中分解某段代码会使代码更具可读性,那么就这样做。

我会这样写,使用转换器

理论上,无论数据结构如何,您都可以更灵活地定义和使用计算

(让[xf(comp(map#)(合并%(第一课详细%)))
(映射(dissoc%:id:series\u id:lession\u id:num))
(映射#(更新%:类型关键字)))]
排成一排,热切地
(进入[]xf课程)
惰性序列
(序列xf课程)

如果您已经在使用传感器,对线程不满意,为什么不继续使用传感器并将
comp
添加到您的第一个版本?@cfrick我尝试了
comp
,但没有成功。如果你想发布一个例子,那就太好了:)你能举一个你的输入和期望输出的例子吗?