यदि यह पहले से ही नहीं है, तो एक ऐरे में तत्व जोड़ें


92

मेरी एक रूबी क्लास है

class MyClass
  attr_writer :item1, :item2
end

my_array = get_array_of_my_class() #my_array is an array of MyClass
unique_array_of_item1 = []

मैं पुश करने के लिए चाहते MyClass#item1करने के लिए unique_array_of_item1, लेकिन केवल तभी unique_array_of_item1है कि शामिल नहीं है item1अभी तक। एक सरल समाधान है जो मुझे पता है: बस के माध्यम से पुनरावृत्त my_arrayकरें और जांचें कि क्या unique_array_of_item1पहले से ही वर्तमान है item1या नहीं।

क्या कोई और अधिक कुशल समाधान है?

जवाबों:


82

आप ऐरे के बजाय सेट का उपयोग कर सकते हैं ।


हालांकि यह सच है कि डॉक्स का कहना है कि सेट ऑर्डर नहीं हैं, वे वास्तव में (रूबी 1.9 के अनुसार) ऑर्डर किए गए हैं। यदि आप कोड को देखते हैं, तो मुख्य विधियों को आप ऑर्डर पर प्राप्त करने के लिए उपयोग करेंगे (जैसे कि Set#eachऔर Set#to_a) @hash। और रूबी के रूप में 1.9 Hashes का आदेश दिया जाता है। "हैश ने अपने मूल्यों को इस क्रम में माना कि संबंधित कुंजियों को डाला गया था।" रूबी-doc.org/core-1.9.1/Hash.html
phylae

नया कभी नहीं था एक सेट के रूप में ऐसी बात थी। वे बहुत बढ़िया हैं, आपको बहुत धन्यवाद
ब्रैड

122

@ कुरासे का अच्छा जवाब है , हालांकि यह होना चाहिए:

my_array | [item]

और my_arrayजगह में अद्यतन करने के लिए :

my_array |= [item]

63
या my_array |= [item]जो my_arrayजगह में अद्यतन करेगा
andorov

2
शायद मैं यहाँ कुछ याद कर रहा हूँ, लेकिन | = ऑपरेटर मेरे लिए काम नहीं करता है? मैं रूबी 2.1.1
वियतनाम

@ |=मेरी 2.1.1 के परीक्षण में ठीक काम करता है। कृपया अपने परीक्षण मामले का वर्णन करें या एक नया प्रश्न खोलें।
depquid

इसे फिर से परीक्षण करना और यह अब काम करता है। पता नहीं मैं पहले क्या कर रहा था क्योंकि मेरी टिप्पणी कई महीने पहले की गई थी।
वियतनाम

1
इसकी जटिलता क्या है?
नोबिता

40

आपको my_arrayहाथ से जाने की जरूरत नहीं है ।

my_array.push(item1) unless my_array.include?(item1)

संपादित करें:

जैसा कि टॉमबार्ट अपनी टिप्पणी में बताते हैं, का उपयोग Array#include?करना बहुत कुशल नहीं है। मैं कहता हूं कि प्रदर्शन प्रभाव छोटे एरर्स के लिए नगण्य है, लेकिन आप Setबड़े लोगों के साथ जाना चाहते हैं।


5
आप निश्चित रूप से ऐसा नहीं करना चाहते हैं! array.include?(item)जटिलता है O(n)- तो यह पूरे सरणी को पुनरावृत्त करने जैसा है। इस बेंचमार्क पर एक नज़र डालें: gist.github.com/deric/4953652
टॉमबार्ट

32

आप item1 को सरणी में बदल सकते हैं और उनमें शामिल हो सकते हैं:

my_array | [item1]

1
ऐसा |नहीं होना चाहिए ||(जेसन का जवाब देखें)
सेठ

1
मेरी गलती। माफ़ करना। उत्तर का
संपादन

3

यह ध्यान रखना महत्वपूर्ण है कि सेट क्लास और | विधि (जिसे "सेट यूनियन" भी कहा जाता है) में अद्वितीय तत्वों की एक सरणी होगी , जो बहुत बढ़िया है यदि आप कोई डुप्लिकेट नहीं चाहते हैं, लेकिन जो एक अप्रिय आश्चर्य होगा यदि आपके पास अपने मूल सरणी में डिज़ाइन द्वारा गैर-अद्वितीय तत्व हैं।

यदि आपके पास अपने मूल सरणी में कम से कम एक डुप्लिकेट तत्व है जिसे आप खोना नहीं चाहते हैं, तो प्रारंभिक रिटर्न के साथ सरणी के माध्यम से पुनरावृत्ति करना सबसे खराब स्थिति O (n) है, जो चीजों की भव्य योजना में बहुत बुरा नहीं है ।

class Array
  def add_if_unique element
    return self if include? element
    push element
  end
end

0

मुझे यकीन नहीं है कि यह सही समाधान है, लेकिन मेरे लिए काम किया है:

    host_group = Array.new if not host_group.kind_of?(Array)
    host_group.push(host)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.