- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在阅读电子书 Functional Programming Patterns in Scala & Clojure并找到了导致这个问题的代码示例。
这段代码的目的是比较两个 Person 对象。比较算法是 - 首先比较它们的 FName,如果相等则比较它们的 LName,如果相等则比较它们的 MName。
书中给出的 Clojure 代码(或多或少)
(def person1 {:fname "John" :mname "Q" :lname "Doe"})
(def person2 {:fname "Jane" :mname "P" :lname "Doe"})
(defn fname-compare [p1 p2]
(do
(println "Comparing fname")
(compare (:fname p1) (:fname p2))))
(defn lname-compare [p1 p2]
(do
(println "Comparing lname")
(compare (:lname p1) (:lname p2))))
(defn mname-compare [p1 p2]
(do
(println "Comparing mname")
(compare (:mname p1) (:mname p2))))
(defn make-composed-comparison [& comparisons]
(fn [p1 p2]
(let [results (for [comparison comparisons] (comparison p1 p2))
first-non-zero-result
(some (fn [result] (if (not (= 0 result)) result nil)) results)]
(if (nil? first-non-zero-result)
0
first-non-zero-result))))
(def people-comparision-1
(make-composed-comparison fname-compare lname-compare mname-compare))
(people-comparision-1 person1 person2)
;Output
;Comparing fname
;Comparing lname
;Comparing mname
;14
事实是,根据此示例,即使第一个返回非零,它也会进行所有三个比较。在这种情况下,这不是问题。但是,如果我编写了惯用的 C# 代码,那么该代码将只进行一次比较并退出。示例 C# 代码
public class Person {
public string FName {get; set;}
public string LName {get; set;}
public string MName {get; set;}
}
var comparators =
new List<Func<Person, Person, int>> {
(p1, p1) => {
Console.WriteLine("Comparing FName");
return string.Compare(p1.FName, p2.FName);
},
(p1, p1) => {
Console.WriteLine("Comparing LName");
return string.Compare(p1.LName, p2.LName);
},
(p1, p1) => {
Console.WriteLine("Comparing MName");
return string.Compare(p1.MName, p2.MName);
}
};
var p1 = new Person {FName = "John", MName = "Q", LName = "Doe"};
var p2 = new Person {FName = "Jane", MName = "P", LName = "Doe"};
var result =
comparators
.Select(x => x(p1, p2))
.Where(x => x != 0)
.FirstOrDefault();
Console.WriteLine(result);
// Output
// Comparing FName
// 1
将上述代码简单地翻译成 clojure 给了我
(defn compose-comparators [& comparators]
(fn [x y]
(let [result
(->> comparators
(map #(% x y))
(filter #(not (zero? %)))
first)]
(if (nil? result)
0
result))))
(def people-comparision-2
(compose-comparators fname-compare lname-compare mname-compare))
(people-comparision-2 person1 person2)
;Output
;Comparing fname
;Comparing lname
;Comparing mname
;14
这不是我所期望的。我在某处读到,出于性能原因或其他原因,clojure 一次处理序列的 32 个元素。获得类似于 C# 代码的输出/行为的惯用 Clojure 方法是什么?
以下是我的尝试。然而,它并不感觉“clojurey”。
(defn compose-comparators-2 [& comparators]
(fn [x y]
(loop [comparators comparators
result 0]
(if (not (zero? result))
result
(let [comparator (first comparators)]
(if (nil? comparator)
0
(recur (rest comparators) (comparator x y))))))))
(def people-comparision-3
(compose-comparators-2 fname-compare lname-compare mname-compare))
(people-comparision-3 person1 person2)
;Output
;Comparing fname
;14
编辑:
基于此问题以及 answer to a related question 的答案,我想如果我需要提前退出,我应该明确表示。一种方法是将集合转换为惰性集合。另一种选择是使用reduced
提前退出reduce 循环。
以我目前掌握的知识,我更倾向于选择显式惰性收集路线。使用以下函数执行此操作是否存在问题 -
(defn lazy-coll [coll]
(lazy-seq
(when-let [s (seq coll)]
(cons (first s) (lazy-coll (rest s))))))
这样我就可以像平常一样使用map
、remove
。
最佳答案
正如您对自己的怀疑以及其他答案所指出的那样,问题在于分块序列并不像它们可能的那样懒惰。
如果我们查看您的 compose-comparators
函数(稍微简化)
(defn compose-comparators [& comparators]
(fn [x y]
(let [result (->> comparators
(map #(% x y))
(remove zero?)
first)]
(if (nil? result) 0 result))))
...所有三个比较都在 people-comparison-2
中运行的原因是 map
处理 block 中的分块序列,如您所见 here 。
一个简单的解决方案是用删除了 block 的 map
替换:
(defn lazy-map [f coll]
(lazy-seq
(when-let [s (seq coll)]
(cons (f (first s)) (lazy-map f (rest s))))))
<小时/>
顺便说一句,您可以抽象比较器函数的构造。如果我们定义
(defn comparer [f]
(fn [x y]
(println "Comparing with " f)
(compare (f x) (f y))))
...我们可以用它来定义
(def people-comparision-2
(apply compose-comparators (map comparer [:fname :lname :mname])))
关于clojure - clojure 是否具有与 C# 等价的 Yield?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26039461/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!