দুটি সম্পত্তি তালিকার একীকরণের কাজ?


11

আমি এই জাতীয় দুটি সম্পত্তি তালিকার একীকরণের জন্য একটি আদর্শ এলিস্প লাইব্রেরি ফাংশন পাইনি:

(setq pl nil)
(setq pl (plist-put pl 'key-1 'value-1))
(setq pl (plist-put pl 'key-2 'value-2))

আমি এর সাথে কিছু তৈরি করতে পারতাম dolist, তবে আমার কাজ করার আগে, আমি তা পরীক্ষা করে দেখতে চাই যে আমি কোনও লাইব্রেরিতে বিদ্যমান ফাংশনটি উপেক্ষা করছি না।

মন্তব্যগুলির উপর ভিত্তি করে আপডেটগুলি :

  1. "বহু উপায়" মন্তব্যের প্রতিক্রিয়া:

আমি কল্পনা করব যে এই জাতীয় কোনও কার্যকারিতা নেই কারণ এই প্রশ্নের উত্তর বিভিন্ন (এবং সম্ভবত বৈধ) সম্ভব রয়েছে: যখন আলাদা মান সহ আপনার নকল সম্পত্তির নাম থাকবে তখন কী করবেন?

হ্যাঁ, সদৃশগুলি কীভাবে মার্জ করা যায় সে সম্পর্কে একটি প্রশ্ন রয়েছে, তবে এটির সমাধানের তুলনামূলকভাবে কয়েকটি উপায় রয়েছে। আমি দুটি সাধারণ পন্থা দেখতে পাচ্ছি। প্রথমত, যুক্তির আদেশ নকলগুলি সমাধান করতে পারে; যেমন ক্লোজুরের সংশ্লেষের মতো ডানদিকের জয় । দ্বিতীয়ত, একীভূতকরণটি রুবির একীকরণের মতো একটি ব্যবহারকারী-সরবরাহিত কলব্যাক ফাংশনে প্রতিনিধি করতে পারে ।

যাই হোক না কেন, এটি করার বিভিন্ন উপায় রয়েছে এই সত্যটি অন্য অনেক ভাষা স্ট্যান্ডার্ড লাইব্রেরিগুলিকে মার্জ ফাংশন সরবরাহ করতে বাধা দেয় না। একই সাধারণ যুক্তি বাছাইয়ের কথা বলা যেতে পারে, এবং তবুও এলিসপ বাছাই কার্যকারিতা সরবরাহ করে।

  1. "আপনি বিস্তারিত বলতে পারেন?" / "দয়া করে আপনি যে আচরণটি সুনির্দিষ্টভাবে সন্ধান করছেন তা নির্দিষ্ট করুন" "

সাধারণভাবে বলতে গেলে, আমি এলিসপ সম্প্রদায় যা ব্যবহার করে তা সম্পর্কে আমি উন্মুক্ত। আপনি যদি একটি নির্দিষ্ট উদাহরণ চান, এখানে একটি উদাহরণ যা কাজ করবে:

(a-merge-function '(k1 1) '(k2 2 k3 3) '(k3 0))

এবং ফিরে

'(k1 1 k2 2 k3 0))

এটি ক্লোজুরের মার্জ হওয়ার মতো, ডান-জয়ের শৈলী হবে।

  1. "এগুলি তালিকাগুলি, তাই কেবল সংযোজন?"

না, সম্পত্তি তালিকার শব্দার্থবিজ্ঞান appendসংরক্ষণ করে না । এই:

(append '(k1 1 k2 2) '(k2 0))

এটি ফেরত দেয়:

(k1 1 k2 2 k2 0)

অ্যাপেনড code সি উত্স কোডে একটি অন্তর্নির্মিত ফাংশন।

(সংযোজন এবং বিশ্রাম SEQUENCES)

সমস্ত তর্ক যুক্ত করুন এবং ফলাফলকে একটি তালিকা করুন। ফলাফল হ'ল একটি তালিকা যার উপাদানগুলি সমস্ত যুক্তির উপাদান। প্রতিটি যুক্তি একটি তালিকা, ভেক্টর বা স্ট্রিং হতে পারে। শেষ যুক্তিটি অনুলিপি করা হয়নি, কেবলমাত্র নতুন তালিকার লেজ হিসাবে ব্যবহৃত হয়েছে।

  1. "এবং আপনার উদাহরণটি মার্জ হওয়ার মতো কিছুই দেখায় না - এটি দুটি সম্পত্তি তালিকারও প্রদর্শন করে না।

হ্যাঁ এটা করে; এটি ধাপে ধাপে মার্জ করে। এটি দেখায় যে কীভাবে এলিস্পের নথিভুক্ত সম্পত্তি তালিকার ফাংশনগুলি ব্যবহার করে একীভূত করা বেদনাদায়ক ভার্বোস:

(setq pl nil)
(setq pl (plist-put pl 'key-1 'value-1))
(setq pl (plist-put pl 'key-2 'value-2))

এর থেকে ফলাফলের ফলাফলটি কেবল প্রদর্শন করুন pl:

(key-1 value-1 key-2 value-2)

পুনরাবৃত্তি করার জন্য, আমি এই সমস্যাটি সমাধান করার জন্য একটি ফাংশন লিখতে সক্ষম, তবে আমি প্রথমে খুঁজে বের করতে চেয়েছিলাম যে এই ধরনের ফাংশন সাধারণ ব্যবহারে কোথাও উপস্থিত রয়েছে কিনা।

অবশেষে, যদি আপনি এই প্রশ্নটিকে অস্পষ্ট বলে মনে করেন তবে আপনি এই বিষয়টিকে অস্বীকার করছেন তবে আমি আপনাকে জিজ্ঞাসা করব যে আপনি এখনই পুনর্বিবেচনা করেছেন যে আমি স্পষ্ট করার জন্য কিছু চেষ্টা করেছি। এটি গবেষণার অভাব নয়। "তালিকাগুলি" সম্পর্কিত এলিস্প ডকুমেন্টেশন প্রশ্নের উত্তর দেয় না।


2
তারা তালিকা, তাই ঠিক append?
অ্যাবো-আবো

2
আপনি যে আচরণটি সুনির্দিষ্টভাবে সন্ধান করছেন দয়া করে উল্লেখ করুন। দুটি তালিকা "মার্জ" করার অনেকগুলি উপায় রয়েছে। এবং আপনার উদাহরণটি মার্জের মতো কিছু দেখায় না - এটি দুটি সম্পত্তি তালিকাও প্রদর্শন করে না। এখনও অবধি, এই প্রশ্নটি অস্পষ্ট হিসাবে বন্ধ করা উচিত। এফডাব্লুআইডাব্লু, সচেতন থাকুন যে একটি প্লিস্টের সামনের কাছাকাছি একটি জুটি সামনের কী থেকে সামনের দিক থেকে দূরে একই চাবিযুক্ত যে কোনও জোড়কে ছায়া দেয়। তাই মার্জ অন্যান্য, ইত্যাদি থেকে উপাদানগুলি আগে এক plist থেকে উপাদানগুলি নির্বাণ অর্থ করতে পারেন
ড্রিউ

1
@ অ্যাবো-অ্যাবো: এটি দেখা যাচ্ছে যে ইমাস লিসপ ম্যানুয়াল স্পষ্টভাবে বলেছে যে সম্পত্তির নাম অবশ্যই পৃথক হওয়া উচিত
কনস্টান্টাইন

3
ডানদিকের তালিকায় জয়লাভ করতে আপনাকে যে তালিকাগুলি পাস করেছে তার ক্রমটি আপনাকে বিপরীত করতে হবে append: (let ((args '((:a 1 :b 1) (:b 2) (:a 3)))) (apply #'append (reverse args))) => (:a 3 :b 2 :a 1 :b 1)যা (:a 3 :b 2 :a 1)আপনি কেবলমাত্র প্লিস্ট অ্যাক্সেস করার জন্য কেবল পলিট ফাংশন ব্যবহার করেন ততক্ষণ একই ।
তারসিউস

1
@ কনস্ট্যান্টাইন: ঠিক আছে, যদিও একাধিক অভিন্ন কী আছে কিনা তা উভয়ই দেখভাল করছেন plist-getনা plist-member। দেখে মনে হচ্ছে তারা এ ব্যাপারে alists করার অনুরূপভাবে আচরণ: (plist-get '(:a "a" :b "b" :a "c") :a) ==> "a"। এদিকে, (plist-put '(:a "a" :b "b" :a "c") :a "d")প্রথম :aকীটির মান প্রতিস্থাপন করে তবে দ্বিতীয়টি নয়।
ড্যান

উত্তর:


8

ইমাক্সের সাথে অন্তর্ভুক্ত অর্গ-মোডের একটি প্লিস্ট মার্জ ফাংশন রয়েছে:

(defun org-combine-plists (&rest plists)
  "Create a single property list from all plists in PLISTS.
The process starts by copying the first list, and then setting properties
from the other lists.  Settings in the last list are the most significant
ones and overrule settings in the other lists."
  (let ((rtn (copy-sequence (pop plists)))
        p v ls)
    (while plists
      (setq ls (pop plists))
      (while ls
        (setq p (pop ls) v (pop ls))
        (setq rtn (plist-put rtn p v))))
    rtn))

এটি ব্যবহার করার জন্য আপনাকে (require 'org)প্রথমে ফাইলটি লোড করতে হবে। দুর্ভাগ্যক্রমে, এটি একটি খুব বড় ফাইল, ৯০০ + কেবি, সুতরাং এটি কোনও ইউটিলিটি লাইব্রেরি হিসাবে সত্যই ব্যবহারযোগ্য নয়। স্ট্যান্ডার্ড প্লিস্ট প্যাকেজের মতো কিছু থাকলে ভাল লাগবে।

আমি সম্প্রতি একটি খুব ছোটটি শুরু করেছি এবং বুঝতে পেরেছি যে তালিকাগুলি এবং তালিকার সাথে একই আচরণ করা হয় না, যুক্তি অনুসারে - উদাহরণস্বরূপ (plist-get LIST KEY) বনাম (এসোসিয়ে কী তালিকা), যা অবশ্যই অপ্টিমাইজেশনের দুর্ভাগ্যজনক চিহ্ন (বা?) হওয়া উচিত ।

তবে, হ্যাঁ, ইমাক্সের জন্য একটি চমৎকার প্লিস্ট লাইব্রেরি দরকার - আমি আমার সন্ধানে একটিরও জুড়ে এসে পৌঁছতে পারি নি, তবে এটি কোথাও কোথাও কোথাও খুঁজে পাওয়া সম্ভব, অন্যথায় আমাদের একটি শুরু করতে হবে এবং এটি এলপা / মেলপাতে লাগাতে হবে ।

একই ইন্টারফেস সহ একটি আলিস্ট্রি লাইব্রেরিটিও ভাল লাগবে।


6

ম্যানুয়ালটি পড়া এবং তালিকাটি থেকে ব্রাউজ C-u C-h a plist RETকরা দুটি সম্পত্তি তালিকার একত্রে ফাংশন চালু করে না। সাধারণ লিস্প এক্সটেনশানগুলি সম্পত্তি তালিকার উপর বিশেষভাবে কাজ করার জন্য কোনও ক্রিয়াকলাপ সরবরাহ করে না, কেবল স্থান ( getf/ setf/…) সমর্থন করে। সুতরাং আপনাকে হয় তৃতীয় পক্ষের লাইব্রেরির উপর নির্ভর করতে হবে বা আপনার নিজস্ব রোল করতে হবে।

আপনার নিজের ঘূর্ণায়মান খুব কঠিন নয়। এই বাস্তবায়ন বিরোধের ক্ষেত্রে সর্বশেষ মানটি ব্যবহার করে।

(defun plist-merge (&rest plists)
  (if plists
      (let ((result (copy-sequence (car plists))))
        (while (setq plists (cdr plists))
          (let ((plist (car plists)))
            (while plist
              (setq result (plist-put result (car plist) (car (cdr plist)))
                    plist (cdr (cdr plist))))))
        result)
    nil))

(plist-merge '(:x 2 :y 3)
             '(     :y 0 :z 7))
=>            (:x 2 :y 0 :z 7)

সুন্দর। আপনি copy-sequenceপ্রথম plist কিন্তু অন্য না কেন ? এবং এছাড়াও, আপনি cadrএবং এর সাথে কিছুটা নীড় পরিষ্কার করতে পারেন cddr
fommil

প্রকৃতপক্ষে, org-combine-plists(নীচে) কম-বেশি ক্লিন আপ সংস্করণ। আমি এখনও বুঝতে পারছি না যে তারা copy-sequenceগাড়ি কেন ।
fommil

0

আমি জানি এটি ইতিমধ্যে উত্তর দেওয়া হয়েছে, তবে যে কেউ আগ্রহী, আমি orgবাস্তবায়ন গ্রহণ করেছি এবং এতে কিছুটা কোড গল্ফ খেললাম

(defun plist-merge (&rest plists)
  "Create a single property list from all PLISTS.
Inspired by `org-combine-plists'."
  (let ((rtn (pop plists)))
    (dolist (plist plists rtn)
      (setq rtn (plist-put rtn
                           (pop plist)
                           (pop plist))))))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.