আমি হ্যাশের প্রতিটি মান পরিবর্তন করতে চাই যাতে এর আগে এবং পরে '%' যুক্ত হয়
{ :a=>'a' , :b=>'b' }
পরিবর্তন করতে হবে
{ :a=>'%a%' , :b=>'%b%' }
এটি করার সর্বোত্তম উপায় কী?
আমি হ্যাশের প্রতিটি মান পরিবর্তন করতে চাই যাতে এর আগে এবং পরে '%' যুক্ত হয়
{ :a=>'a' , :b=>'b' }
পরিবর্তন করতে হবে
{ :a=>'%a%' , :b=>'%b%' }
এটি করার সর্বোত্তম উপায় কী?
উত্তর:
যদি আপনি প্রকৃত স্ট্রিংগুলি নিজের জায়গায় পরিবর্তিত করতে চান (সম্ভবত এবং একই স্ট্রিং অবজেক্টের অন্যান্য রেফারেন্সগুলিকে আকাঙ্ক্ষিতভাবে প্রভাবিত করুন):
# Two ways to achieve the same result (any Ruby version)
my_hash.each{ |_,str| str.gsub! /^|$/, '%' }
my_hash.each{ |_,str| str.replace "%#{str}%" }
আপনি যদি হ্যাশটি পরিবর্তিত করতে চান তবে আপনি স্ট্রিংগুলিকে প্রভাবিত করতে চান না (আপনি এটি নতুন স্ট্রিংগুলি পেতে চান):
# Two ways to achieve the same result (any Ruby version)
my_hash.each{ |key,str| my_hash[key] = "%#{str}%" }
my_hash.inject(my_hash){ |h,(k,str)| h[k]="%#{str}%"; h }
আপনি যদি একটি নতুন হ্যাশ চান:
# Ruby 1.8.6+
new_hash = Hash[*my_hash.map{|k,str| [k,"%#{str}%"] }.flatten]
# Ruby 1.8.7+
new_hash = Hash[my_hash.map{|k,str| [k,"%#{str}%"] } ]
Hash.[]
অ্যারে জোড়গুলির একটি অ্যারে গ্রহণ করে না, এটির জন্য সরাসরি সংখ্যার যুক্তিগুলির একটি বৃহত পরিমাণ প্রয়োজন (তাই সামনে স্প্ল্যাট আপ)।
Hash#each
কী এবং মান উভয়ই দেয়। এই ক্ষেত্রে, আমি কীটির বিষয়ে চিন্তা করিনি, এবং তাই আমি এটির কোনও কার্যকর নামকরণ করি নি। পরিবর্তনশীল নামগুলি একটি আন্ডারস্কোর দিয়ে শুরু হতে পারে এবং বাস্তবে কেবল একটি আন্ডারস্কোর হতে পারে । এটি করার কোনও কার্যকারিতা সুবিধা নেই, এটি কেবল একটি সূক্ষ্ম স্ব-ডকুমেন্টিং নোট যে আমি প্রথম ব্লকের মানটি দিয়ে কিছুই করছি না।
my_hash.inject(my_hash){ |h,(k,str)| h[k]="%#{str}%"; h }
, ব্লক থেকে হ্যাশটি ফিরিয়ে দিতে হবে
রুবি ২.১ এবং এর চেয়ে বেশি আপনি করতে পারেন
{ a: 'a', b: 'b' }.map { |k, str| [k, "%#{str}%"] }.to_h
#transform_values!
sschmeck (দ্বারা সরু আউট হিসাবে stackoverflow.com/a/41508214/6451879 )।
রুবি ২.৪ পদ্ধতিটি চালু করেছে Hash#transform_values!
, যা আপনি ব্যবহার করতে পারেন।
{ :a=>'a' , :b=>'b' }.transform_values! { |v| "%#{v}%" }
# => {:a=>"%a%", :b=>"%b%"}
Hash#transform_values
(ঠুং ঠুং শব্দ ছাড়া), যা রিসিভারটি পরিবর্তন করে না। অন্যথায় দুর্দান্ত উত্তর, ধন্যবাদ!
হ্যাশের মানগুলিকে পরিবর্তিত করার সর্বোত্তম উপায় হ'ল
hash.update(hash){ |_,v| "%#{v}%" }
কম কোড এবং পরিষ্কার উদ্দেশ্য। আরও দ্রুত কারণ কোনও নতুন অবজেক্টকে যে মানগুলি পরিবর্তিত করতে হবে তার বাইরে বরাদ্দ দেওয়া হয়নি।
gsub!
।
update
চেয়ে ভাল উদ্দেশ্য জানাতে merge!
। আমি মনে করি এটিই সেরা উত্তর।
k
ব্যবহার না করেন তবে _
পরিবর্তে ব্যবহার করুন।
কিছুটা আরও পঠনযোগ্য, map
এটি একক-উপাদান হ্যাশগুলির একটি অ্যারে এবং এটির reduce
সাথেmerge
the_hash.map{ |key,value| {key => "%#{value}%"} }.reduce(:merge)
Hash[the_hash.map { |key,value| [key, "%#{value}%"] }]
Array
(এর জন্য map
) তারপর ক Hash
। তারপরে হ্রাস অপারেশনের প্রতিটি পদক্ষেপ "মেমো "টিকে নকল করবে Hash
এবং এতে নতুন কী-মান জুটি যুক্ত করবে। অন্তত ব্যবহার এ :merge!
মধ্যে reduce
চূড়ান্ত সংশোধন করার Hash
জায়গায়। এবং শেষ অবধি, আপনি বিদ্যমান বস্তুর মানগুলি পরিবর্তন করছেন না বরং একটি নতুন অবজেক্ট তৈরি করছেন, যা প্রশ্নটি জিজ্ঞাসা করে না what
nil
থাকলে ফিরে আসেthe_hash
এই টাস্কের জন্য একটি নতুন 'রেল ওয়ে' পদ্ধতি রয়েছে :) http://api.rubyonrails.org/classes/Hash.html#method-i-transfor_values
Hash#transform_values
। এখন থেকে এই পথ চলতে হবে।
একটি পদ্ধতি যা মূলটির সাথে পার্শ্ব প্রতিক্রিয়াগুলি প্রবর্তন করে না:
h = {:a => 'a', :b => 'b'}
h2 = Hash[h.map {|k,v| [k, '%' + v + '%']}]
হ্যাশ # মানচিত্রটি একটি আকর্ষণীয় পঠন হতে পারে কারণ এটি ব্যাখ্যা করেHash.map
হ্যাশ ফেরত আসে না (যার কারণে জোড়গুলির ফলে অ্যারেটি [key,value]
নতুন হ্যাশে রূপান্তরিত হয়) এবং একই সাধারণ প্যাটার্নের বিকল্প পন্থা সরবরাহ করে।
শুভ কোডিং।
[অস্বীকৃতি: Hash.map
রুবি ২.x তে শব্দার্থবিজ্ঞানের পরিবর্তন হয়েছে কিনা তা আমি নিশ্চিত নই ]
Hash.map
রুবি ২.x-তে শব্দার্থবিজ্ঞানের পরিবর্তন কিনা তাও জানেন ?
my_hash.each do |key, value|
my_hash[key] = "%#{value}%"
end
each_with_object
রুবি ১.৯ (আইআইআরসি) রয়েছে যা সরাসরি নাম অ্যাক্সেস করার প্রয়োজন এড়িয়ে যায় এবং Map#merge
এটি কাজও করতে পারে। কীভাবে জটিল বিশদগুলি পৃথক হয় তা নিশ্চিত নয়।
আরএসপেক দিয়ে এটির মতো পরীক্ষার পরে:
describe Hash do
describe :map_values do
it 'should map the values' do
expect({:a => 2, :b => 3}.map_values { |x| x ** 2 }).to eq({:a => 4, :b => 9})
end
end
end
আপনি নিম্নরূপে হ্যাশ # মানচিত্র_ মানগুলি প্রয়োগ করতে পারেন:
class Hash
def map_values
Hash[map { |k, v| [k, yield(v)] }]
end
end
ফাংশনটি এভাবে ব্যবহার করা যেতে পারে:
{:a=>'a' , :b=>'b'}.map_values { |v| "%#{v}%" }
# {:a=>"%a%", :b=>"%b%"}
যদি আপনি কৌতূহলী হন তবে কোন স্থানের রূপটি এখানে দ্রুত হয় তা হল:
Calculating -------------------------------------
inplace transform_values! 1.265k (± 0.7%) i/s - 6.426k in 5.080305s
inplace update 1.300k (± 2.7%) i/s - 6.579k in 5.065925s
inplace map reduce 281.367 (± 1.1%) i/s - 1.431k in 5.086477s
inplace merge! 1.305k (± 0.4%) i/s - 6.630k in 5.080751s
inplace each 1.073k (± 0.7%) i/s - 5.457k in 5.084044s
inplace inject 697.178 (± 0.9%) i/s - 3.519k in 5.047857s