2016-03-23 12 views
0

Bir talebin alınmasının ardından, bir dış kaynaktan alınan değerleri almam, filtrelemem ve filtrelenmiş değerleri arayana geri göndermem gerekir. Bir seferde dış kaynaktan belirli bir miktarda kayıt getirerek sonucu (istenen boyuta ulaşıncaya kadar) biriktiriyorum. Bir çözüm bulmayı başardım, ancak bunu yapmanın en zarif veya deyimsel yolu olup olmadığından emin değilim.Clojure - Bir Döngünün İçinde Bir Vektörü Doldurmak için İmanatik Yol

Lütfen aşağıdaki yanıt kodlama işlevinin çağrılan ilk 50 sayıyı arayan kişiye döndürmesi gereken simüle edilmiş kodu inceleyin. (Bu kodun kenar kasalarını kullanamayacağını unutmayın, ancak bence gösterim amacıyla yeterince iyi olduğunu düşünüyorum).

Belki atom yerine ref kullanmalıyım? Herhangi bir öneriniz için şimdiden teşekkür ederiz.

(defn fetch [start] 
    (let [end (+ start 10)] 
    (range start end))) 

(defn take-good-ones [all] 
    (filter odd? all)) 

(defn make-response [] 
    (let [start (atom 0) 
     result (atom [])] 
    (while (< (count @result) 50) 
     (do 
     (let [all-values (fetch @start) 
      good-values (take-good-ones all-values) 
      handled-this-time (count all-values)] 
     (swap! start + handled-this-time) 
     (swap! result concat good-values)))) 
    @result)) 

cevap

3

atomu veya düşük-seviye döngü malzeme mutasyona gerek yoktur:

daha
; the next 10 items since start 
(defn fetch [start] 
    (range start (+ 10 start))) 

; lazy sequence of good values, by getting batches of 10 from `fetch` 
(defn all-good-values [] 
    (filter odd? 
     (mapcat #(fetch (* 10 %)) (range)))) 

(defn make-response [] 
    (take 20 (all-good-values))) 

(make-response) => (1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39) 
+0

Çok güzel. Teşekkür ederim. Ancak, girdi belirli bir değere ulaştığında getirme işlevinin boş yanıtları döndürmeye başladığı durumu nasıl ele alırsınız? Örneğin, getirme herhangi biri için boş değerler döndürürse (başlangıç> 50) ve yanıtlamada 50 tane alırsınız? Bu durumda yanıt çağrısını sonlandırmak olmaz. Bu tembel dizi şeylerinin özünü seviyorum, ama onu kucaklarken bazı zorluklar yaşıyorum. – Mohamed

+0

Merhaba @ Bir deyim yerindeyse, bu, "kaynak" sekansının, getiriler boş yanıtları döndürmeye başladığında bittiğinden emin olmaktır. Daha sonra girişe uygulanan sıralama işleme fonksiyonu (filtre, al, vs.) otomatik olarak sona erer. –

0

Joost's answer için, toplu her biri daha sonra, filtre birleştirilmiş, yani karıştırma etkisi yoktur edilir. Bu nedenle etki sadece

(defn make-response [] 
    (->> (range) (filter odd?) (take 50))) 
İlgili konular