ভেরিয়েবল হ্যাশ বা অ্যারে কিনা তা বলতে রুবিতে একটি মার্জিত উপায় কী?


140

কি তা যাচাই করতে @some_varআমি একটি করছি

if @some_var.class.to_s == 'Hash' 

আমি নিশ্চিত যে চেক করার আরও একটি মার্জিত উপায় আছে কিনা @some_varতা একটি Hashবা একটি Array


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

2
তাহলে তুমি পাবে [result_hash, another_result_hash]নাকি single_result_hash? যে এপিআই তৈরি করেছে সে ভাল কাজ করছে না!
অ্যান্ড্রু গ্রিম

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

আমার কাছে @ ড্রাইডের মতো অবস্থা রয়েছে। আমার ক্ষেত্রে তৃতীয় পক্ষটি এইচটিটিপি পার্টি যা কোনও এক্সএমএল ফাইল পার্স করার পরে কোনও এলিমেন্টের 1-এন বাচ্চা থাকতে পারে এমন পরিস্থিতি পরিচালনার সর্বোত্তম উপায় কোনটি তা সিদ্ধান্ত নেওয়ার উপায় নেই।
ডার্টি হেনরি

আপনার অ্যাভিডি গ্রিমস স্ক্রিনকাস্টটি দেখতে হবে: রুবটাপাস.কম / ২০১/10 / ২০১/ / ১/ / পর্ব-451- অ্যাডভান্সড- ক্লাস- মেম্বারশিপ এবং সম্ভবত ক্যাবসকে গৃহীতটির উত্তর দিন make
আলেকজান্ডার প্রেসার

উত্তর:


261

আপনি ঠিক করতে পারেন:

@some_var.class == Hash

বা এর মতো কিছু:

@some_var.is_a?(Hash)

"যে_এ?" পদ্ধতিটি সত্য যদি শ্রেণিটি বস্তুর পূর্বপুরুষের গাছের যে কোনও জায়গায় থাকে। এই ক্ষেত্রে:

@some_var.is_a?(Object)  # => true

উপরেরটি সত্য যদি @ সোম_ভর হ্যাশ বা অন্য শ্রেণীর উদাহরণ যা অবজেক্ট থেকে আসে। সুতরাং, আপনি যদি শ্রেণীর ধরণের উপর একটি কঠোর ম্যাচ চান, == বা উদাহরণ_আর ব্যবহার করে? পদ্ধতি সম্ভবত আপনি যা খুঁজছেন হয়।


20
is_a?এটি সর্বোত্তম বিকল্প, যেহেতু এটি trueসাবক্লাসগুলির জন্যও ফিরে আসে ।
Fábio Batista

এবং অবশ্যই, আপনি বন্ধনীগুলিও ছেড়ে দিন, তাই @som_var.is_a? Hashখুব কার্যকরী :)
গাস শর্টজ

7
সাবধানতা অবলম্বন করুন, যদি কেউ আপনাকে অ্যাক্টিভসপোর্ট :: হ্যাশ উইথআইডিফলারঅ্যাক্সেসের একটি উদাহরণ দিয়ে শেষ করে তবে এটি আপনাকে সত্যই স্ক্রু করতে পারে। যা হ্যাশের মতো সাড়া দেয় তবে বাস্তবে হ্যাশ নয়। :(
ফুল

আমি হাঁসের টাইপিংয়ের বিষয়ে বিস্তারিতভাবে আরও উত্তর পছন্দ করতে পছন্দ করলাম, যেহেতু মূল লেখক স্পষ্টতই কোনও ধরণের চেক করার জন্য রুবি খুঁজছিলেন।
নোবডিসনিটমায়ার

3
@ আনফ্লোরগুলি ActiveSupport::HashWithIndifferentAccessহ্যাশের উত্তরাধিকার সূত্রে, সুতরাং @some_var.is_a?(Hash)এ ক্ষেত্রেও সত্য ফিরে আসবে। (আমার ঠিক একই প্রশ্ন ছিল এবং হাশউইথআইডিফিলিস্টেন্স অ্যাক্সেস কেস এবং আপনার মন্তব্য থেকে কিছুটা বিভ্রান্ত হয়ে পড়েছিলাম ... তাই আমি স্পষ্ট করে বলতে চেয়েছিলাম)
স্টিলজক

38

প্রথমত, আক্ষরিক প্রশ্নের সর্বোত্তম উত্তর হ'ল

Hash === @some_var

তবে এখানে কীভাবে হাঁস-টাইপিং করবেন তা দেখিয়ে সত্যই প্রশ্নের উত্তর দেওয়া উচিত ছিল। এটি আপনার কোন ধরণের হাঁসের প্রয়োজন তা কিছুটা নির্ভর করে।

@some_var.respond_to?(:each_pair)

অথবা

@some_var.respond_to?(:has_key?)

অথবা এমনকি

@some_var.respond_to?(:to_hash)

অ্যাপ্লিকেশন উপর নির্ভর করে সঠিক হতে পারে।


25

সাধারণত রুবিতে যখন আপনি "টাইপ" সন্ধান করেন আপনি আসলে "হাঁসের ধরণ" চান বা "কি হাঁসের মতো কোঁকড়ানো?" আপনি দেখতে পাবেন যে এটি কোনও নির্দিষ্ট পদ্ধতির প্রতিক্রিয়া জানায়:

@some_var.respond_to?(:each)

আপনি @ সোেম_ওয়ারের মাধ্যমে পুনরাবৃত্তি করতে পারেন কারণ এটি প্রতিক্রিয়া জানায়: প্রতিটি

আপনি যদি প্রকৃতপক্ষে প্রকারটি জানতে চান এবং যদি এটি হ্যাশ বা অ্যারে হয় তবে আপনি এটি করতে পারেন:

["Hash", "Array"].include?(@some_var.class)  #=> check both through instance class
@some_var.kind_of?(Hash)    #=> to check each at once
@some_var.is_a?(Array)   #=> same as kind_of

যদি আপনার কোডটি ডেটার ক্রম (যেমন আপনি প্রতিটি_বিহীন_আডেক্স ব্যবহার করছেন) এর উপর নির্ভর করে তবে এটি কাজ করবে না। উপাদানের ক্রম হ্যাশ এবং অ্যারে মধ্যে ভিন্নভাবে বাস্তবায়িত হয় এবং এটি রুবি সংস্করণের মধ্যে ভিন্ন (। Intertwingly.net/slides/2008/oscon/ruby19/22 )
juan2raid

1
@ জুয়ান 2 ভয়: যদি অর্ডারটি গুরুত্বপূর্ণ sortহয় তবে প্রথমে এটিতে কল করুন।
অ্যান্ড্রু গ্রিম

দ্বিতীয় উদাহরণ @Brandon স্ট্রিং বর্গ রূপান্তর করা উচিত <br/>।["Hash", "Array"].include?(@some_var.class.to_s) #=> check both through instance class
OBCENEIKON

12
Hash === @some_var #=> return Boolean

এটি কেস স্টেটমেন্টের সাথেও ব্যবহার করা যেতে পারে

case @some_var
when Hash
   ...
when Array
   ...
end

4

আমি এটি ব্যবহার:

@var.respond_to?(:keys)

এটি হ্যাশ এবং অ্যাক্টিভসপোর্ট :: হাশউইথআইডিফিলারঅ্যাক্সেসের জন্য কাজ করে।


4

অনুশীলনে, আপনি প্রায়শই কেবল বলাই নয়, ভেরিয়েবল একটি অ্যারে বা হ্যাশ কিনা তার উপর নির্ভর করে আপনি ভিন্নভাবে কাজ করতে চান different এই পরিস্থিতিতে, একটি মার্জিত আইডিয়োম নিম্নলিখিত:

case item
  when Array
   #do something
  when Hash
   #do something else
end

মনে রাখবেন যে আপনি .classপদ্ধতিটি কল করেন না item


2

তুমি ব্যবহার করতে পার instance_of?

যেমন

@some_var.instance_of?(Hash)

নোট করুন যে এটি সাবক্লাসের জন্য কাজ করে না ! উদাহরণস্বরূপ, আপনার যদি ActiveRecord::Collectionচেষ্টা করে থাকে instance_of?(Array)তবে এটি ফিরে আসবে false, যেখানে is_a?(Array)ফিরে আসবে true
টম লর্ড

0

যদি আপনি পরীক্ষা করতে চান যে কোনও বিষয় কঠোরভাবে বা কোনওটি প্রসারিত করে Hash, ব্যবহার করুন:

value = {}
value.is_a?(Hash) || value.is_a?(Array) #=> true

তবে রুবির হাঁসের টাইপিংয়ের মান বানাতে আপনি এমন কিছু করতে পারেন:

value = {}
value.respond_to?(:[]) #=> true

আপনি যখন কেবল value[:key]সিনট্যাক্স ব্যবহার করে কিছু মান অ্যাক্সেস করতে চান তা কার্যকর হয় ।

দয়া করে নোট করুন যে Array.new["key"]একটি উত্থাপন করবে TypeError


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