سؤال

أحاول تنفيذ وظيفة "تخفيض الخريطة". أي أنه يجب أن يعيد تسلسلًا يتكون من نتيجة التقديم f إلى أول 2 العناصر من coll, ، تليها نتيجة التقديم f إلى هذه النتيجة والبند الثالث في coll, ، إلخ.

(def c [[0 0 0 0] [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]])

(defn- sum-vector [v1 v2]
  (map + v1 v2))

(defn reduce-map [f coll & acc]
  (if (< (count coll) 2)
    (if (empty? acc) coll acc)
    (let [head (apply f (take 2 coll))
          tail (drop 2 coll)]
      (recur f (conj tail head) (conj acc head)))))

على سبيل المثال ، استدعاء هذه الوظيفة مثل هذه:

(reduce-map sum-vector c)

يجب أن تعود:

[[1 0 0 0] [1 1 0 0] [1 1 1 0] [1 1 1 1]]

(في الواقع ، من المحتمل أن يعيد العنصر الأول غير المعدل أيضًا ، لتقليد أفضل map, ، لكن يمكنني إصلاح ذلك لاحقًا.)

الآن ، الآن ، هذا ما يعيده:

((1 1 1 1) (1 1 1 0) (1 1 0 0) (1 0 0 0))

كيف يمكنني "الدفع" في نهاية A (NY) seq؟

إذا استبدلت reduce-map إلى عن على recur, ، هذا ما يعود إليه:

(((1 1 1 1) ((1 1 1 0) ((1 1 0 0) ((1 0 0 0))))))

ماهو الفرق بين recur والروح الحقيقية في الكود الخاص بي أعلاه؟

و، هل هناك طريقة مدمجة ، أو أفضل ، أو أكثر احتمالا ، للتنفيذ reduce-map?

أخيرًا ، أود أن يكون تسلسل الإخراج كسولًا. هل ألف كل شيء في lazy-seq?

هل كانت مفيدة؟

المحلول

هذا يبدو وكأنه يشبه قليلا reductions.

أما بالنسبة لـ "الدفع" في نهاية SEQ: في SEQS ، لا تملك "نهاية" ، راجع (iterate inc 0).

فيما يتعلق بـ "الدفع" في نهاية القائمة: لا يتم تصميم القوائم لذلك. استخدم ناقل. بذرة المتراكم الخاص بك مع [], ، ليس nil.

بما يخص lazy-seq: استخدم العودية "الحقيقية" بدلاً من recur. مثال هنا:

(defn integer-seq
  [start]
  (lazy-seq
    (cons start (integer-seq (inc start)))))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top