【问题标题】:Clojure: apply vs reduce for converting integers to chars and stringsClojure:应用与减少将整数转换为字符和字符串
【发布时间】:2014-04-13 07:15:35
【问题描述】:

以下两个函数都返回相同的输出,但第一个函数使用 reduce 和一对引号来实现相同的目的。我玩过这段代码,如果你删除"" 标记,序列中的第一个字符不会从它的整数值转换。第二种对我来说似乎很清楚,但我觉得第一种方法更好,因为它将所有想要的效果打包到一个函数文字中。有人可以为我解压缩匿名函数来解释%%2 指的是什么变量,并告诉我为什么我们只需要向量中的第一个整数(115)使用""

 (reduce #(str % (char %2)) ""
            [115 101 99 114 101 116 32 109 101 115 115 97 103 101 115])

 (apply str (map #(char %) [115 101 99 114 101 116 32 109 101 115 115 97 103 101 115]))

第一个函数取自 Clojure Cookbook 关于intstr 转换、here 的讨论。

【问题讨论】:

  • 仅供参考 #(char %) 在行为上与 char 相同,但由于额外的间接性可能会更慢。

标签: string clojure char apply reduce


【解决方案1】:

可以找到匿名函数阅读器宏here

匿名函数字面量(#())

#(...) => (fn [args] (...))

其中 args 由参数文字的存在决定 %、%n 或 %& 形式。 % 是 %1 的同义词,%n 指定第 n 个参数 (从 1 开始),并且 %& 指定一个剩余 arg。这不是替代品 fn - 惯用的用于非常短的一次性映射/过滤器 fns 之类的。 #() 表单不能嵌套。

%%1 指第一个参数,%2 指第二个。

在您的情况下,在第一种方法中,% 指的是""%2 指的是整数向量; 在第二种方法中,% 到整数向量。

至于reduceapply 之间的区别,reduce 提供了一个提供的val,在您的情况下为""。如果没有这个""reduce 将调用str115(char 101),这将产生"115e"。不应使用向量中的第一个和第二个元素调用str,而应使用空字符串和向量的第一个元素调用str,这将产生"s"。而在下一个 reduce 循环中,str 将使用参数"s"101 调用,产生"se",以此类推。

对于apply 调用,您在调用apply 之前已将char 映射到整数向量,因此apply 的参数将是: 1. 函数str; 2.函数map产生的字符向量。

此外,您可以在this question 中查看有关applyreduce 之间差异的更多信息。

【讨论】:

  • 明确地说,匿名函数#(str % (char %2))(fn [x y] (str x (char y)))的简写。
  • 感谢您的详尽。我想我很惊讶在第一次迭代期间“”会与第 0 个向量元素混为一谈。我仍然只了解大约 85% 的情况,但仔细检查 reduce 函数在后台发生了什么应该会有所帮助。
【解决方案2】:

reduce 采用可选的第一个值,否则它会按原样从集合中获取第一个元素并开始减少集合的其余部分。这会起作用,但会改变你的收藏

(reduce #(str %1 (char %2))
        ["" 101 99 114 101 116 32 109 101 115 115 97 103 101 115])

最好先映射然后再减少

(reduce str 
  (map (comp str char) 
    [115 101 99 114 101 116 32 109 101 115 115 97 103 101 115]))

或者正如下面的noisesmith所说,下面的内容更加清晰

(reduce str 
  (map char
    [115 101 99 114 101 116 32 109 101 115 115 97 103 101 115]))

【讨论】:

  • 你可以用char替换(comp str char)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 2019-10-16
  • 2012-02-21
相关资源
最近更新 更多