更新时间:2022-10-15 12:20:40
clojure-1.7.0-alpha1
具有此函数的正确版本,名称 重复数据删除
。
您引用的一个会返回其输入序列,而不会连续重复。 (几乎可以肯定地),如果它们开始输入序列,它也会吞下所有连续的 nil
值。
#(if(not(=(last%1)%2)
(conj%1%2)
%1)
lambda减少说:如果累加器的最后一个元素(%1
)不等于下一个输入元素(%2
),将其添加到累加器,否则返回累加器。
因为(last [])
计算为 nil
当累加器为空时,它不会添加 nil
值。我将这个练习作为练习留给读者:
确保重复
返回预期结果 [nil true nil]
for input [nil nil true true nil]
。 b
$ b
注意:使用向量操作时,使用 peek
的性能明显优于 last
。
EDIT (由于您编辑了您的问题): distinct
的输入序列只有一次。与 set
不同,它返回lazy-sequence。
一种更惯用的方式来写重复
/ 重复数据删除
是A. Webb发布为评论(因为它也是懒惰)。否则,使用空累加器作为其输入,并使用 peek
而不是最后
不是固定lambda, clojure-1.7.0-alpha1
c $ c> dedupe 传感器,用于急切评估,e。 g。:
(into [](dedupe)[nil nil true true nil])
- > [nil true nil]
或者为了延迟评估:
(dedupe [nil nil true true nil])
- > (nil true nil)
I made this function to remove consecutive duplicates, but I wanted to know if there was a better or shorter way to express it using distinct
or something like that.
(defn duplicates
[s]
(reduce
#(if-not (= (last %1) %2)
(conj %1 %2) %1)
[] s))
clojure-1.7.0-alpha1
has a correct version of this function under the name dedupe
.
The one you quoted returns its input sequence without consecutive duplicates. (Almost certainly) unwittingly, it also swallows all successive nil
values if they begin the input sequence.
#(if-not (= (last %1) %2)
(conj %1 %2)
%1)
The lambda to reduce says: If the last element of the accumulator (%1
) is unequal to the next input element (%2
), add it to the accumulator, otherwise return the accumulator.
Because (last [])
evaluates to nil
it will never add nil
values while the accumulator is empty. I leave fixing that as an exercise to the reader:
Make sure that duplicates
returns the expected result [nil true nil]
for input [nil nil true true nil]
.
Note: When operating with a vector, using peek
performs significantly better than last
.
EDIT (Since you edited your question): distinct
returns each value of the input sequence only once. Unlike set
it returns lazy-sequence.
A more idiomatic way to write duplicates
/dedupe
is the one that A. Webb posted as a comment (since it is also lazy). Otherwise, fixing the lambda to work correctly with an empty accumulator as its input and using peek
instead of last
would be more idiomatic.
Instead of fixing the lambda, in clojure-1.7.0-alpha1
you would use the dedupe
transducer for eager evaluation, e. g.:
(into [] (dedupe) [nil nil true true nil])
-> [nil true nil]
Or for lazy evaluation:
(dedupe [nil nil true true nil])
-> (nil true nil)