[1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10
আমি এই কোডটি দেখছি কিন্তু আমার মস্তিষ্ক কীভাবে 10 নম্বর ফলাফল হতে পারে তা নিবন্ধভুক্ত করছে না। এখানে কি ঘটছে তা বোঝানোর জন্য কেউ মনে করবে?
[1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10
আমি এই কোডটি দেখছি কিন্তু আমার মস্তিষ্ক কীভাবে 10 নম্বর ফলাফল হতে পারে তা নিবন্ধভুক্ত করছে না। এখানে কি ঘটছে তা বোঝানোর জন্য কেউ মনে করবে?
উত্তর:
আপনি প্রথম ব্লকের আর্গুমেন্টটিকে একটি সংযোজক হিসাবে ভাবতে পারেন: ব্লকের প্রতিটি রানের ফলাফল সংগ্রহকারীর মধ্যে সংরক্ষণ করা হয় এবং তারপরে ব্লকের পরবর্তী কার্যনির্বাহীতে চলে যায়। উপরের দেখানো কোডের ক্ষেত্রে, আপনি সংগ্রহকারীকে ডিফল্ট করছেন, ফলাফল, 0 এ। ব্লকের প্রতিটি রান বর্তমান সংখ্যায় প্রদত্ত সংখ্যাটি যুক্ত করে এবং তারপরে ফলাফলটিকে পুনরায় সঞ্চয়ের মধ্যে সংরক্ষণ করে। পরবর্তী ব্লক কলের এই নতুন মান রয়েছে, এতে যুক্ত হয়, এটি আবার সঞ্চয় করে এবং পুনরাবৃত্তি করে।
প্রক্রিয়া শেষে, ইনজেক্টটি জমা করে দেয়, যা এই ক্ষেত্রে অ্যারে বা 10 এর সমস্ত মানের যোগফল।
স্ট্রিং প্রতিনিধিত্ব করে কীডযুক্ত বস্তুর অ্যারে থেকে একটি হ্যাশ তৈরি করার জন্য এখানে আরও একটি সহজ উদাহরণ রয়েছে:
[1,"a",Object.new,:hi].inject({}) do |hash, item|
hash[item.to_s] = item
hash
end
এই ক্ষেত্রে, আমরা আমাদের সংগ্রহকারীটিকে একটি খালি হ্যাশে ডিফল্ট করছি, তারপরে প্রতিবার ব্লকটি কার্যকর করে এটিকে পপুলেট করে। লক্ষ্য করুন আমাদের অবশ্যই হ্যাশটিকে ব্লকের শেষ লাইন হিসাবে ফিরিয়ে আনতে হবে, কারণ ব্লকের ফলস্বরূপ সংগ্রহকারীর মধ্যে পুনরায় জমা হবে।
result + explanation
হ'ল সংস্থানকারী এবং ফেরতের মান উভয়কে রূপান্তর। এটি একটি অন্তর্নিহিত রিটার্ন করে এটি ব্লকের শেষ লাইন।
inject
( 0
আপনার উদাহরণে) এবং একটি ব্লক দিয়ে শুরু করার জন্য একটি মান নেয় এবং এটি তালিকার প্রতিটি উপাদানগুলির জন্য একবারে সেই ব্লকটি চালায়।
result + element
) সংরক্ষণ করে।এটি ব্যাখ্যা করার সবচেয়ে সহজ উপায় হ'ল প্রতিটি উদাহরণ কীভাবে কাজ করে তা উদাহরণস্বরূপ; এই ফলাফলটি কীভাবে মূল্যায়ন করা যেতে পারে তা দেখানোর একটি কল্পিত সেট:
[1, 2, 3, 4].inject(0) { |result, element| result + element }
[2, 3, 4].inject(0 + 1) { |result, element| result + element }
[3, 4].inject((0 + 1) + 2) { |result, element| result + element }
[4].inject(((0 + 1) + 2) + 3) { |result, element| result + element }
[].inject((((0 + 1) + 2) + 3) + 4) { |result, element| result + element }
(((0 + 1) + 2) + 3) + 4
10
ইনজেক্ট পদ্ধতির বাক্য গঠনটি নিম্নরূপ:
inject (value_initial) { |result_memo, object| block }
আসুন উপরের উদাহরণটি সমাধান করুন
[1, 2, 3, 4].inject(0) { |result, element| result + element }
যা আউটপুট হিসাবে 10 দেয় ।
সুতরাং, শুরু করার আগে আসুন দেখুন প্রতিটি ভেরিয়েবলের মধ্যে কী কী মান রয়েছে:
ফলাফল = 0 শূন্যটি ইনজেকশন থেকে এসেছে (মান) যা 0 is
উপাদান = 1 এটি অ্যারের প্রথম উপাদান।
ঠিক আছে !!! সুতরাং, আসুন উপরের উদাহরণটি বুঝতে শুরু করা যাক
ধাপ 1 [1, 2, 3, 4].inject(0) { |0, 1| 0 + 1 }
ধাপ ২ [1, 2, 3, 4].inject(0) { |1, 2| 1 + 2 }
ধাপ 3 [1, 2, 3, 4].inject(0) { |3, 3| 3 + 3 }
পদক্ষেপ: 4 [1, 2, 3, 4].inject(0) { |6, 4| 6 + 4 }
পদক্ষেপ: 5 [1, 2, 3, 4].inject(0) { |10, Now no elements left in the array, so it'll return 10 from this step| }
এখানে বোল্ড-ইটালিক মান হ'ল অ্যারে থেকে সরানো এবং সহজভাবে বোল্ড elements মানগুলি ফলস্বরূপ মান।
আমি আশা করি আপনি #inject
পদ্ধতিটির কাজটি বুঝতে পেরেছেন #ruby
।
তারা কী বলেছিল, তবে এগুলিও নোট করুন যে আপনার সর্বদা "শুরুর মান" সরবরাহ করার দরকার নেই:
[1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10
হিসাবে একই
[1, 2, 3, 4].inject { |result, element| result + element } # => 10
চেষ্টা করে দেখুন, আমি অপেক্ষা করব।
যখন কোনও যুক্তি ইনজেকশনে পাস করা হয় না, প্রথম দুটি উপাদান প্রথম পুনরাবৃত্তিতে পাস হয়। উপরের উদাহরণে, ফলাফলটি 1 এবং উপাদানটি প্রথমবারের মতো 2 হয়, তাই ব্লকে আরও কম কল করা হয়।
আপনার ইনজেকশনের () এর ভিতরে থাকা নম্বরটি একটি শুরুর স্থান উপস্থাপন করে, এটি 0 বা 1000 হতে পারে the পাইপগুলির ভিতরে আপনার দুটি স্থানধারক রয়েছে | x, y | x =। ইনজেক্ট ('x') এর ভিতরে আপনার যে সংখ্যাটি ছিল এবং সেকেন্ডটি আপনার বস্তুর প্রতিটি পুনরাবৃত্তির প্রতিনিধিত্ব করে।
[1, 2, 3, 4].inject(5) { |result, element| result + element } # => 15
1 + 5 = 6 2 + 6 = 8 3 + 8 = 11 11 + 4 = 15
ইনজেকশন ব্লক প্রয়োগ করে
result + element
অ্যারে প্রতিটি আইটেম। পরবর্তী আইটেমের জন্য ("উপাদান"), ব্লক থেকে প্রাপ্ত মানটি "ফলাফল"। আপনি যেভাবে এটি (প্যারামিটার সহ) বলেছেন, সেই ফলাফলটির সাথে "ফলাফল" শুরু হয় result সুতরাং প্রভাব উপাদান যোগ করা হয়।
tldr; একটি গুরুত্বপূর্ণ উপায়ে inject
পৃথক map
: inject
ব্লকের শেষ সম্পাদনের মান প্রদান করে যেখানে map
এটির পুনরাবৃত্তি হওয়া অ্যারেরটি দেয়।
এর চেয়েও বেশি প্রতিটি ব্লক এক্সিকিউশনের মান প্রথম প্যারামিটারের মাধ্যমে পরবর্তী এক্সিকিউশনে ( result
এই ক্ষেত্রে) পাস হয়ে যায় এবং আপনি সেই মানটি আরম্ভ করতে পারেন ((0)
অংশটি) ।
আপনার উপরের উদাহরণটি map
এভাবে ব্যবহার করে লেখা যেতে পারে :
result = 0 # initialize result
[1, 2, 3, 4].map { |element| result += element }
# result => 10
একই প্রভাব কিন্তু inject
এখানে আরও সংক্ষিপ্ত।
আপনি প্রায়শই একটি অ্যাসাইনমেন্টটি map
ব্লকে ঘটে দেখবেন , অন্যদিকে ব্লকটিতে একটি মূল্যায়ন ঘটে inject
।
আপনি কোন পদ্ধতিটি বেছে নেবেন তা আপনি যে সুযোগ চান তা নির্ভর করে result
। কখন ব্যবহার করবেন না তা এই জাতীয় কিছু হবে:
result = [1, 2, 3, 4].inject(0) { |x, element| x + element }
আপনি সবার মতো হতে পারেন, "আমাকে দেখুন, আমি এগুলি কেবল একটি লাইনে সংযুক্ত করেছি," তবে আপনি x
একটি স্ক্র্যাচ ভেরিয়েবল হিসাবে অস্থায়ীভাবে মেমরিও বরাদ্দ দিয়েছিলেন যেহেতু আপনাকে ইতিমধ্যে result
কাজ করতে হবে বলে প্রয়োজনীয় ছিল না ।
[1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10
নিম্নলিখিতগুলির সমতুল্য:
def my_function(r, e)
r+e
end
a = [1, 2, 3, 4]
result = 0
a.each do |value|
result = my_function(result, value)
end
[1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10
সরল ইংরেজিতে, আপনি এই অ্যারে ( [1,2,3,4]
) এর মাধ্যমে (পুনরাবৃত্তি) যাচ্ছেন । আপনি এই অ্যারেটি দিয়ে 4 বার পুনরাবৃত্তি করতে পারবেন, কারণ এখানে 4 টি উপাদান রয়েছে (1, 2, 3 এবং 4)। ইনজেকশন পদ্ধতিতে 1 টি যুক্তি (সংখ্যা 0) রয়েছে এবং আপনি সেই যুক্তিটি 1 ম এলিমেন্টে যুক্ত করবেন (0 + 1. এটি সমান 1)। 1 "ফলাফল" এ সংরক্ষিত হয়েছে। তারপরে আপনি সেই ফলাফলটি (যা 1) পরবর্তী উপাদানগুলিতে যুক্ত করুন (1 + 2. এটি 3)। এটি এখন ফলাফল হিসাবে সংরক্ষণ করা হবে। চালিয়ে যান: 3 + 3 সমান 6. এবং অবশেষে, 6 + 4 সমান 10 হয়।
এই কোডটি প্রারম্ভিক মানটি পাস না করার সম্ভাবনাটিকে অনুমতি দেয় না, তবে যা চলছে তা ব্যাখ্যা করতে সহায়তা করতে পারে।
def incomplete_inject(enumerable, result)
enumerable.each do |item|
result = yield(result, item)
end
result
end
incomplete_inject([1,2,3,4], 0) {|result, item| result + item} # => 10
এখান থেকে শুরু করুন এবং তারপরে যে সমস্ত পদ্ধতিগুলি ব্লকগুলি নিয়ে থাকে তা পর্যালোচনা করুন। http://ruby-doc.org/core-2.3.3/Enumerable.html#method-i-inject
এটি কি সেই ব্লক যা আপনাকে বিভ্রান্ত করে বা কেন আপনার পদ্ধতিতে একটি মূল্য রয়েছে? ভাল প্রশ্ন যদিও। সেখানে অপারেটর পদ্ধতি কী?
result.+
এটি কি হিসাবে শুরু হয়?
#inject(0)
আমরা কি এটা করতে পারি?
[1, 2, 3, 4].inject(0) { |result, element| result.+ element }
এটা কি কাজ করে?
[1, 2, 3, 4].inject() { |result = 0, element| result.+ element }
আপনি দেখতে পাচ্ছেন আমি এই ধারণাটি তৈরি করছি যে এটি অ্যারের সমস্ত উপাদানগুলিকে কেবল পরিমাণে যোগ করে এবং ডক্সে আপনি যে মেমো দেখেন তাতে একটি সংখ্যা দেয় yield
আপনি সর্বদা এটি করতে পারেন
[1, 2, 3, 4].each { |element| p element }
অ্যারের সংখ্যাটি পুনরাবৃত্তি হতে দেখতে। এটিই মূল ধারণা।
এটি কেবলমাত্র ইনজেকশন বা হ্রাস হ'ল আপনাকে একটি মেমো বা কোনও প্রেরক পাঠানো হয় accum
আমরা একটি ফলাফল পেতে চেষ্টা করতে পারে
[1, 2, 3, 4].each { |result = 0, element| result + element }
কিন্তু কিছুই ফিরে আসে না তাই এটি ঠিক আগের মতোই কাজ করে
[1, 2, 3, 4].each { |result = 0, element| p result + element }
উপাদান পরিদর্শক ব্লক।
এটি ব্যাখ্যাটি বোঝার জন্য একটি সহজ এবং মোটামুটি সহজ:
"প্রাথমিক মান" সম্পর্কে ভুলে যান কারণ এটি শুরুতে কিছুটা বিভ্রান্তিকর।
> [1,2,3,4].inject{|a,b| a+b}
=> 10
আপনি উপরের বিষয়গুলি বুঝতে পারবেন: আমি 1,2,3,4 এর মধ্যে একটি "অ্যাডিং মেশিন" ইনজেকশন দিচ্ছি। অর্থ, এটি 1 ♫ 2 ♫ 3 ♫ 4 এবং ♫ একটি অ্যাডিং মেশিন, তাই এটি 1 + 2 + 3 + 4 এর সমান এবং এটি 10 হয়।
আপনি আসলে +
তাদের মধ্যে একটি ইনজেক্ট করতে পারেন :
> [1,2,3,4].inject(:+)
=> 10
এবং এটি এর মতো, +
1,2,3,4 এর মধ্যে একটি ইনজেক্ট করুন , এটি 1 + 2 + 3 + 4 তৈরি করে এবং এটি 10। :+
এটি রুবিকে +
প্রতীক আকারে নির্দিষ্ট করার পদ্ধতি।
এটি বোঝা বেশ সহজ এবং স্বজ্ঞাত। এবং যদি আপনি পর্যায়ক্রমে এটি কীভাবে কাজ করে তা বিশ্লেষণ করতে চান তবে এটির মতো: 1 এবং 2 গ্রহণ করে এখন সেগুলি যুক্ত করুন এবং ফলস্বরূপ, প্রথমে এটি সংরক্ষণ করুন (যা 3) এবং এখন, পরবর্তীটি সঞ্চিত রয়েছে মান 3 এবং অ্যারের উপাদান 3 একটি + বি প্রসেসের মধ্য দিয়ে যাচ্ছে, যা 6, এবং এখন এই মানটি সংরক্ষণ করে এখন 6 এবং 4 এ + বি প্রক্রিয়াটির মধ্য দিয়ে যায় এবং 10 হয় আপনি মূলত করছেন
((1 + 2) + 3) + 4
এবং 10 "" প্রাথমিক মান "দিয়ে শুরু 0
হওয়া কেবল একটি" বেস "। অনেক ক্ষেত্রে, আপনার এটির দরকার নেই। আপনার যদি 1 * 2 * 3 * 4 প্রয়োজন হয় এবং এটি হয় তা কল্পনা করুন
[1,2,3,4].inject(:*)
=> 24
এবং এটি সম্পন্ন হয়েছে। 1
পুরো জিনিসটি দিয়ে গুণতে আপনার কোনও "প্রাথমিক মান" লাগবে না 1
।
.আইনজেক্ট () পদ্ধতির অন্য একটি রূপ রয়েছে যা খুব সহায়ক [4,5]। ইনজেক্ট (&: +) যা এই অঞ্চলের সমস্ত উপাদানকে যুক্ত করবে