如何从 Clojure 中的列表中复制项目?

问题描述 投票:0回答:5

我已经尝试了很多个夜晚,最终我放弃了自己。似乎是一个非常简单的问题,但我想我只是没有完全理解 Clojure (我部分地将其归因于我几乎唯一的命令式语言经验)。问题来自 hackerrank.com

问题来了:

Problem Statement


 Given a list repeat each element of the list n times. The input and output 
portions will be handled automatically by the grader.

Input Format 
    First line has integer S where S is the number of times you need to repeat 
elements. After this there are X lines, each containing an integer. These are the 
X elements of the array.

Output Format 
    Repeat each element of the original list S times. So you have to return 
list/vector/array of S*X integers. The relative positions of the values should be 
same as the original list provided as input.

Constraints 
0<=X<=10 
1<=S<=100

所以,鉴于:

2
1
2
3

输出:

1
1
2
2
3
3

我已经尝试过:

(fn list-replicate [num list]
    (println (reduce 
        (fn [element seq] (dotimes [n num] (conj seq element)))
        []
        list))
)

但这只是给了我一个例外。我已经尝试了很多其他解决方案,这可能不是我更好的解决方案之一,但它是我能想到的在此处发布内容的最快解决方案。

list clojure
5个回答
3
投票
(defn list-replicate [num list]
  (mapcat (partial repeat num) list))

(doseq [x (list-replicate 2 [1 2 3])]
  (println x))

;; output:
1
1 
2
2
3 
3

3
投票

前面的答案很短,也有效,但是很“压缩”,对于新人来说不容易学习。我会用一种更简单、更明显的方式来做。

首先看

repeat
函数:

user=> (doc repeat)
-------------------------
clojure.core/repeat
([x] [n x])
  Returns a lazy (infinite!, or length n if supplied) sequence of xs.

user=> (repeat 3 5)
(5 5 5)

所以我们看到如何轻松地重复某件事 N 次。

如果我们对列表的每个元素运行(重复 n ...)会怎样?

(def N 2)
(def xvals [1 2 3] )
(for [curr-x xvals]
  (repeat N curr-x))
;=> ((1 1) (2 2) (3 3))

我们已经很接近了,但是我们有一个用于输出的列表列表。怎么修?最简单的方法是使用

flatten
函数:

(flatten
  (for [curr-x xvals]
    (repeat N curr-x)))
;=> (1 1 2 2 3 3)

请注意,

repeat
for
都是惰性函数,除非我真的需要它们,否则我宁愿避免它们。另外,我通常更喜欢将线性集合存储在具体的向量中,而不是通用的“seq”类型。由于这些原因,我添加了一个额外步骤,将结果强制转换为最终产品的单个(eagar)向量:

(defn list-replicate [num-rep orig-list]
  (into []
    (flatten
      (for [curr-elem xvals]
        (repeat N curr-elem)))))

(list-replicate N xvals)
;=> [1 1 2 2 3 3]

1
投票

我建议构建艾伦的解决方案,而不是使用 concat 进行扁平化,因为这将保留数据的结构,以防您输入像这样的 [[1 2] [3 4]]。

    ((fn [coll] (apply concat (for [x coll] (repeat 2 x)))) [[1 2] [3 4]])

    output: => ([1 2] [1 2] [3 4] [3 4])

与展平不同,它执行以下操作

    ((fn [coll] (flatten (for [x coll] (repeat 2 x)))) [[1 2] [3 4]])

    output: => (1 2 1 2 3 4 3 4)

对于简单的列表,例如'(1 2 3),效果是一样的:

   ((fn [coll] (apply concat (for [x coll] (repeat 2 x)))) '(1 2 3))

   output => (1 1 2 2 3 3)

0
投票
(reduce #(count (map println (repeat %1 %2))) num list)

0
投票
(fn [num lst] (for [e lst _ (range num)] (println e)))

与 lambda 相同:

#(for [e %2 _ (range %)] (println e))
© www.soinside.com 2019 - 2024. All rights reserved.