একটি সম্পত্তি তালিকা জুড়ে একটি ফাংশন মানচিত্র?


17

প্রশ্ন: কোনও সম্পত্তি তালিকার জুড়ে কোনও ফাংশন ম্যাপ করার অলঙ্কৃত উপায় কী?

বিভিন্ন ম্যাপিং ফাংশন ( mapcarএবং পরিবার) একটি ক্রম যেমন একটি তালিকার উপরে একটি ফাংশন মানচিত্র করে। কোনও সম্পত্তি তালিকার সাথে কাজ করার সময় এই ফাংশনগুলি কীভাবে ব্যবহার করা যায় , যখন তালিকায় থাকা প্রতিটি সম্পত্তি জুড়ে ম্যাপ করার চেষ্টা করার সময় (যা প্রথমটি থেকে শুরু করে প্রতিটি উপাদান হবে)? আমার কাছে মনে হচ্ছে ম্যাপিং ফাংশনটির জন্য পৃথক উপাদানগুলির পরিবর্তে উপাদানগুলির জোড়াতে তালিকাটি অ্যাক্সেস করা দরকার।

খেলনার উদাহরণ হিসাবে, কেউ কীভাবে একটি সম্পত্তি তালিকা গ্রহণ করবে এবং সমস্ত সম্পত্তি মান সংগ্রহ করবে? পরিবর্তে এটি যদি সমিতির তালিকা হত তবে এটি বেশ সহজ হবে:

(mapcar #'cadr '((:prop1 a) (:prop2 b) (:prop3 c))) ;=> (a b c)

আমি নিশ্চিত যে এটি একটি লুপ দিয়ে সম্পন্ন করা যেতে পারে তবে এটি কিছুটা শ্রমসাধ্য বলে মনে হচ্ছে এবং আমি আরও অবাক হয়েছি যে এটি করার আরও কোনও বুদ্ধিমান উপায় নেই।


আপনি কেবল সম্পত্তির মানগুলি (যা এটির মতো মনে হচ্ছে, এবং এটি যা আপনার বিকল্প mapcarউদাহরণটি দেখায়) মানচিত্র করতে চান কিনা তা দয়া করে স্পষ্ট করুন বা সম্পত্তি চিহ্ন এবং সম্পত্তি মানের জোড়গুলির উপর আপনি ম্যাপ করতে চান। পরেরটি আরও সাধারণ (আরও সাধারণভাবে দরকারী), আমি অনুমান করব।
ড্রিউ

@ ড্রু: আমি সাধারণ ক্ষেত্রে আরও আগ্রহী; উদাহরণটি হ'ল আমি ভাবতে পারি সবচেয়ে সহজ। আমি কীভাবে সম্পত্তি / মান জুটির উপরে মানচিত্র তৈরি করতে চাই তা জানতে চাই । যদি উত্তরটি "একটি লুপ" হয় তবে তা হ'ল তবে আমি আরও ভাবছি যে এর থেকে আরও মার্জিত সমাধান আছে কিনা।
ড্যান

আপনার উদাহরণে যা আছে তা কোনও সম্পত্তি তালিকা নয়। সম্পত্তি তালিকার এমনকি সংখ্যক উপাদান রয়েছে, বিজোড় উপাদানগুলি সম্পত্তির নাম এবং এমনকি উপাদানগুলি সম্পত্তির মান। আপনার যা আছে, সম্ভবত একটি গাছ বলা হবে (তালিকার একটি তালিকা)।
wvxvw

উত্তর:


8

আপনি সম্ভবত বিভিন্ন loopএবং পুনরাবৃত্তি উত্তর পেতে হবে । আফাইক, এটি করার মতো কোনও মূ .় উপায় নেই। আমি কেবল সম্পত্তির মানগুলি সংগ্রহ করতে চাই না বলে মনে করি না (সম্পত্তিগুলির সাথে তাদের সংযুক্ত না করে)।

এটি করার একটি সহজ উপায় এখানে:

(defun prop-values (plist)
  "..."
  (let ((pl    (cdr plist))
        (vals  ()))
    (while pl
      (push (car pl) vals)
      (setq pl  (cddr pl)))
    (nreverse vals)))

আরও সাধারণ ক্ষেত্রে, যেখানে আপনি একটি প্লিস্টের উপর বাইনারি ফাংশনটি মানচিত্র করতে চান:

(defun map-plist (fn plist)
  "..."
  (let ((pl    plist)
        (vals  ()))
    (while pl
      (push (funcall fn (car pl) (cadr pl)) vals)
      (setq pl (cddr pl)))
    (nreverse vals)))

(setq foo '(a 1 b 2 c 3 d 4 e 5))

(map-plist #'cons foo) ; => ((a . 1) (b . 2) (c . 3) (d . 4) (e . 5))

13

এটি সম্ভবত কোনও পরিস্থিতির উপর নির্ভর করবে। সাধারণভাবে, যদি আমাকে বেশ কয়েকটি নামের সাথে কয়েকটি মান বাঁধতে হয় তবে আমি একটি হ্যাশ-টেবিল ব্যবহার করব, তবে যদি আমার কোনও সম্পত্তি তালিকা ব্যবহার করতে হয় তবে আমি ব্যবহার করব cl-loop। নীচে কয়েকটি উদাহরণ দেওয়া হল:

(cl-loop for (key value) on '(:prop1 a :prop2 b :prop3 c) by 'cddr
         collect value)
;;; (a b c)

এবং যদি আপনার কাছে ডেটা-কাঠামো থাকে তবে আপনি উদাহরণটিতে দেখান:

(cl-loop for (key value) in '((:prop1 a) (:prop2 b) (:prop3 c))
         collect value)
;;; (a b c)

5

আমার কাছে উত্তরটি হ'ল প্লিস্টটিকে একটি অ্যালিস্টে পরিণত করা, যা একটি সমতুল্য ডেটা-কাঠামো, ঠিক অর্ধেক গভীর এবং ম্যানিপুলেট করা সহজ।


3
ঠিক আছে, এটি একটি উত্তর (এবং ভাল পরামর্শ), কিন্তু একটি মন্তব্য আরও।
ড্র করেছেন

4

বর্তমান গিট হেড থেকে ইম্যাকস যা ইমাস 25 হয়ে যাবে, আপনি নিম্নলিখিতটি করতে পারেন, অর্থাত্ প্লাস্টটিকে নতুন seq-partitionফাংশন দিয়ে সহজেই একটি তালিকায় পরিণত করতে পারেন , এবং তারপরে স্ট্যান্ডার্ড ব্যবহার করে আলিস্ট্রি এন্ট্রি প্রসেস করতে পারেন mapcar

(let* ((my-plist (list :a 1 :b 2 :c 3 :more (list 4 5 6)))
       (my-alist (seq-partition my-plist 2))
       (my-reverse-alist (mapcar (lambda (entry)
                                   (let ((prop (car entry))
                                         (val  (cadr entry)))
                                     (list val prop)))
                                 my-alist)))
  (message "my-plist: %s\nmy-alist: %s\nmy-reverse-alist: %s"
           my-plist my-alist my-reverse-alist))
;; my-plist: (:a 1 :b 2 :c 3 :more (4 5 6))
;; my-alist: ((:a 1) (:b 2) (:c 3) (:more (4 5 6)))
;; my-reverse-alist: ((1 :a) (2 :b) (3 :c) ((4 5 6) :more))

কটাক্ষপাত আছে seq-partitionব্যবহার ডক্স C-h f seq-partition RET


1

একটি ধারণা ব্যবহার করা -map-indexedথেকে dashএবং শুধুমাত্র তালিকার বিজোড় মান রূপান্তর প্রযোজ্য:

(-non-nil (-map-indexed (lambda (index item) (when (oddp index) item))
  '(a x b y c z))) ; => (x y z)
(-non-nil (--map-indexed (when (oddp it-index) it) '(a x b y c z))) ; => (x y z)

অন্য ধারণাটি হ'ল একটি প্লাস্টটিকে কেবল হ্যাশ-টেবিলে রূপান্তর করা, এর মাধ্যমে ব্যবহার ht<-plistকরে ht:

(ht-values (ht<-plist '(a x b y c z) 'equal)) ; (z y x)

লক্ষ্য করুন যে হ্যাশ-টেবিল আইটেমগুলির ক্রম সংরক্ষণ করে না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.