রুবিতে একটি .এচ লুপের শেষ বলুন


91

যদি আমার যেমন লুপ থাকে

users.each do |u|
  #some code
end

যেখানে ব্যবহারকারীরা একাধিক ব্যবহারকারীর একটি হ্যাশ। আপনি ব্যবহারকারীদের হ্যাশের শেষ ব্যবহারকারীর মধ্যে রয়েছেন এবং কেবলমাত্র সেই শেষ ব্যবহারকারীর জন্য নির্দিষ্ট কোডটি কার্যকর করতে চান তা দেখতে সবচেয়ে সহজ শর্তযুক্ত যুক্তিটি কী?

users.each do |u|
  #code for everyone
  #conditional code for last user
    #code for the last user
  end
end

আপনি কি সত্যিই একটি হ্যাশ বোঝাতে চান? হ্যাশের উপর অর্ডার করা সর্বদা নির্ভরযোগ্য নয় (আপনি কীভাবে হ্যাশগুলিতে জিনিস যুক্ত করেন এবং আপনি কী রুবি সংস্করণ ব্যবহার করছেন তার উপর নির্ভর করে)। অবিশ্বস্ত অর্ডার দিয়ে 'শেষ' আইটেমটি সামঞ্জস্যপূর্ণ হবে না। প্রশ্নের কোড এবং আপনি যে উত্তরগুলি পাচ্ছেন তা কোনও অ্যারে বা গণনার পক্ষে বেশি উপযুক্ত। উদাহরণস্বরূপ, হ্যাশগুলির কোনও পদ্ধতি each_with_indexবা lastপদ্ধতি নেই।
শ্যাডওয়েল

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

অবশ্যই, বেশ সঠিক, hashes আছে each_with_indexক্ষমা চাই। হ্যাঁ, আমি দেখতে পাচ্ছি যে এটি উঠে আসবে; শুধু প্রশ্নটি পরিষ্কার করার চেষ্টা করছি। ব্যক্তিগতভাবে আমার জন্য সর্বোত্তম উত্তরটি হ'ল ব্যবহার .lastতবে এটি হ্যাশের জন্য প্রয়োগ হয় না কেবল একটি অ্যারে।
শ্যাডওয়েল

রুবি / রেলে একটি লুপে ম্যাজিক প্রথম এবং শেষ সূচকটির সদৃশ ? এটির চেয়ে অ্যারে পরিবর্তে হ্যাশ হওয়া ছাড়াও।
অ্যান্ড্রু গ্রিম

4
@ অ্যান্ড্রু সম্পূর্ণরূপে এটির সাথে একমত, তবে মেগারের দুর্দান্ত উত্তরটি দেখায় যে এটি ঠিক কীভাবে ডুপ নয়।
স্যাম জাফরান

উত্তর:


147
users.each_with_index do |u, index|
  # some code
  if index == users.size - 1
    # code for the last user
  end
end

4
এটির সাথে সমস্যা হ'ল শর্তসাপেক্ষে প্রতিটি সময়ই এটি চালানো হয়। .lastলুপ বাইরে ব্যবহার করুন ।
বেকারম্যান

4
আমি কেবল এটি যোগ করব যদি আপনি একটি হ্যাশ দিয়ে পুনরাবৃত্তি করেন তবে আপনাকে এটি লিখতে হবে:users.each_with_index do |(key, value), index| #your code end
হাব

আমি জানি এটি পুরোপুরি একই প্রশ্ন নয়, তবে এই কোডটি আরও ভাল কাজ করে আমি মনে করি আপনি যদি শেষ ব্যবহারকারীর বাট সবাইকে কিছু করতে চান তবে আমি যেটাকে খুঁজছিলাম তা থেকেই আমি উজ্জীবিত হচ্ছি
হোয়াইটটাইগার

38

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

তবে, আপনি সমস্ত ব্যবহারকারীর জন্য একই কোড এবং শেষ ব্যবহারকারীর জন্য কিছু অতিরিক্ত কোড চালাচ্ছেন বলে মনে হচ্ছে । যদি এটি হয় তবে এটি আরও সঠিক বলে মনে হচ্ছে এবং আপনার উদ্দেশ্যটি আরও স্পষ্টভাবে জানিয়েছে:

users.each do |u|
  #code for everyone
end

users.last.do_stuff() # code for last user

4
শর্তসাপেক্ষে প্রয়োজন না হলে +1, যদি এটি উপযুক্ত হয়। (অবশ্যই, আমি এখানে করেছি)
জেরেমি

@ মায়াগার এই লুপ ট্রুপ ব্যবহারকারীদের দু'বার করবে না?
পিপীলিকা

@ না না, একটি লুপ এবং একটি কল .lastরয়েছে যার সাথে লুপিংয়ের কোনও সম্পর্ক নেই।
মেগার

@ মায়াগার যাতে শেষের দিকে যাওয়ার জন্য এটি শেষ উপাদানটি অভ্যন্তরীণভাবে লুপ করে না? এটি লুপ ছাড়া সরাসরি উপাদান অ্যাক্সেস করার একটি উপায় আছে?
পিপীলিকা

4
@ না না, এতে কোনও অভ্যন্তরীণ লুপ জড়িত নেই .last। সংগ্রহটি ইতিমধ্যে তাত্ক্ষণিকভাবে রয়েছে, এটি কেবল একটি অ্যারের সহজ সরল অ্যাক্সেস। এমনকি যদি সংগ্রহটি ইতিমধ্যে লোড না করা হত (যেমন এটি এখনও একটি অহিড্রেটেড অ্যাক্টিভেকর্ড সম্পর্ক) lastতখনও সর্বশেষ মানটি অর্জন করতে কখনই লুপ হয় না , এটি বুনোভাবে অক্ষম হবে। এটি সর্বশেষ রেকর্ডটি ফিরে আসার জন্য কেবল এসকিউএল কোয়েরিটি পরিবর্তন করে। তাই বলা হয়, এই সংগ্রহটি ইতিমধ্যে দ্বারা লোড করা হয়েছে .each, তাই আর জটিলতা পেলে আপনি কি করতেন চেয়ে জড়িত x = [1,2,3]; x.last
মেগার

20

আমি মনে করি একটি সেরা পন্থা:

users.each do |u|
  #code for everyone
  if u.equal?(users.last)
    #code for the last user
  end
end

22
এই উত্তরটির সাথে সমস্যাটি হ'ল যদি শেষ ব্যবহারকারীরও তালিকায় আগে উপস্থিত হয়, তবে শর্তসাপেক্ষ কোডটি একাধিকবার কল হবে।
evanrmurphy

4
আপনাকে ব্যবহার করতে হবে u.equal?(users.last), equal?পদ্ধতিটি অবজেক্ট_আইডিটির সাথে তুলনা করে, বস্তুর মান নয়। তবে এটি চিহ্ন এবং সংখ্যা নিয়ে কাজ করবে না।
নফাফা বুতেফার



3

কখনও কখনও আমি যুক্তিটিকে দুটি ভাগে পৃথক করা ভাল বলে মনে করি, সমস্ত ব্যবহারকারীর জন্য একটি এবং শেষের জন্য একটি। সুতরাং আমি এই জাতীয় কিছু করব:

users[0...-1].each do |user|
  method_for_all_users user
end

method_for_all_users users.last
method_for_last_user users.last

3

আপনি @ বা মাঝারি পদ্ধতির ব্যবহারের ক্ষেত্রে / বা পরিস্থিতির জন্যও ব্যবহার করতে পারেন, যেখানে আপনি সর্বশেষ ব্যবহারকারীর ব্যতীত সকলের জন্য কিছু কোড প্রয়োগ করছেন এবং তারপরে কেবলমাত্র শেষ ব্যবহারকারীর জন্য কিছু অনন্য কোড।

users[0..-2].each do |u|
  #code for everyone except the last one, if the array size is 1 it gets never executed
end

users.last.do_stuff() # code for last user

এইভাবে আপনার শর্তসাপেক্ষের দরকার নেই!


@ বেনিবেলা নং, [-1] শেষ উপাদান। নেই [-0]। সুতরাং দ্বিতীয় থেকে শেষ হয় [-2]।
কোডারুবি

users[0..-2]যেমনটি ঠিক তেমন সঠিক users[0...-1]। বিভিন্ন রেঞ্জ অপারেটর ..বনাম নোট করুন ..., দেখুন স্ট্যাকওভারফ্লো.com
এলিয়ট সাইকেস

2

আরেকটি সমাধান হ'ল স্টপ ইন্টেরেশন থেকে উদ্ধার:

user_list = users.each

begin
  while true do
    user = user_list.next
    user.do_something
  end
rescue StopIteration
  user.do_something
end

4
এটি এই সমস্যার ভাল সমাধান নয়। ব্যতিক্রমগুলি সাধারণ প্রবাহ নিয়ন্ত্রণের জন্য অপব্যবহার করা উচিত নয়, তারা ব্যতিক্রমী পরিস্থিতিতে রয়েছে।
মেগার

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

4
@ কর্তৃপক্ষ "কর্তৃত্বের পক্ষ থেকে তর্ক" করার জন্য দুঃখিত, তবে ম্যাটজ আপনার সাথে একমত নন। আসলে, StopIterationলুপের প্রস্থানগুলি পরিচালনা করার সুনির্দিষ্ট কারণে ডিজাইন করা হয়েছে। ম্যাটের বই থেকে: "এটি অস্বাভাবিক বলে মনে হতে পারে an অপ্রত্যাশিত এবং ব্যতিক্রমী ঘটনার পরিবর্তে প্রত্যাশিত সমাপ্তির শর্তের জন্য একটি ব্যতিক্রম উত্থাপিত হয় ((এর StopIterationবংশধর StandardErrorএবং IndexError; নোট করুন যে এটি কেবল ব্যতিক্রম শ্রেণীর মধ্যে একটি যা শব্দটি নেই এর নামে "ত্রুটি")) রুবি এই বাহ্যিক পুনরাবৃত্তি
কৌশলটিতে

(...) লুপ সমাপ্তিকে ব্যতিক্রম হিসাবে গণ্য করে, এটি আপনার লুপিং যুক্তিটিকে অত্যন্ত সহজ করে তোলে; nextপুনরাবৃত্ত মানের কোনও বিশেষ-পুনরাবৃত্ত মানের জন্য next?next
পুনরুদ্ধার

4
@Adamantish এটা লক্ষনীয় যে loop doএকটি অন্তর্নিহিত রয়েছে rescueএকটি সম্মুখীন StopIteration; বাহ্যিকভাবে কোনও Enumeratorবস্তুর পুনরাবৃত্তি করার সময় এটি বিশেষত ব্যবহৃত হয় । loop do; my_enum.next; endপুনরাবৃত্তি হবে my_enumএবং শেষে প্রস্থান করবে ; সেখানে কোনও লাগানোর দরকার rescue StopIterationনেই। (আপনি যদি ব্যবহার করেন whileবা আপনার করতে হবে until))
ববরোডস

0

রুবির কয়েকটি সংস্করণের জন্য হ্যাশের জন্য শেষ পদ্ধতি নেই

h = { :a => :aa, :b => :bb }
last_key = h.keys.last
h.each do |k,v|
    puts "Put last key #{k} and last value #{v}" if last_key == k
end

এটি কি এমন উত্তর যা অন্য কারও উত্তরকে উন্নত করে? কোন উত্তরটি 'শেষ' পদ্ধতির উল্লেখ করেছে এবং এই সমস্যাটি কাটিয়ে ওঠার জন্য আপনি কী প্রস্তাব দিয়েছেন তা পোস্ট করুন।
আর্টেমিক্স

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