আমি এই উভয় ফাংশন fold()
এবং reduce()
কোটলিনে খুব বিভ্রান্ত , কেউ কি আমাকে একটি দৃ me় উদাহরণ দিতে পারেন যা উভয়কেই আলাদা করে?
আমি এই উভয় ফাংশন fold()
এবং reduce()
কোটলিনে খুব বিভ্রান্ত , কেউ কি আমাকে একটি দৃ me় উদাহরণ দিতে পারেন যা উভয়কেই আলাদা করে?
উত্তর:
fold
একটি প্রাথমিক মান নেয় এবং আপনি যে ল্যাম্বডায় পাস করেন তার প্রথম অনুরোধটি সেই প্রাথমিক মানটি এবং পরামিতি হিসাবে সংগ্রহের প্রথম উপাদানটি গ্রহণ করবে।
উদাহরণস্বরূপ, নিম্নলিখিত কোডটি নিন যা পূর্ণসংখ্যার তালিকার সমষ্টি গণনা করে:
listOf(1, 2, 3).fold(0) { sum, element -> sum + element }
ল্যাম্বডায় প্রথম কলটি প্যারামিটার সহ 0
এবং থাকবে 1
।
আপনার ক্রিয়াকলাপের জন্য যদি আপনাকে কোনও ধরণের ডিফল্ট মান বা প্যারামিটার সরবরাহ করতে হয় তবে প্রাথমিক মানটিতে পাস করার ক্ষমতাটি কার্যকর। উদাহরণস্বরূপ, আপনি যদি কোনও তালিকার মধ্যে সর্বাধিক মান সন্ধান করেন তবে কোনও কারণে কমপক্ষে 10 টি ফিরে আসতে চান, আপনি নিম্নলিখিতটি করতে পারেন:
listOf(1, 6, 4).fold(10) { max, element ->
if (element > max) element else max
}
reduce
প্রাথমিক মান গ্রহণ করে না, তবে পরিবর্তে সংগ্রহের প্রথম উপাদানটির সাথে শুরু হয় ( sum
নিম্নলিখিত উদাহরণে বলা হয়)।
উদাহরণস্বরূপ, আসুন আবার সংখ্যার যোগফল করব:
listOf(1, 2, 3).reduce { sum, element -> sum + element }
এখানে ল্যাম্বডায় প্রথম কলটি হবে প্যারামিটার 1
এবং সহ 2
।
আপনি reduce
যখন ব্যবহার করতে পারেন তখন আপনার অপারেশন আপনি যে সংগ্রহটিতে প্রয়োগ করছেন সেগুলি বাদে অন্য কোনও মানের উপর নির্ভর করে না।
emptyList<Int>().reduce { acc, s -> acc + s }
একটি ব্যতিক্রম উত্পাদন করবে, তবে emptyList<Int>().fold(0) { acc, s -> acc + s }
তা ঠিক আছে।
listOf<Int>(1, 2).reduce { acc: Number, i: Int -> acc.toLong() + i }
-টাইপ হতে পারে: এটি কাজ করে (তালিকা-টাইপটি ইন্ট থাকে এবং
আমি যে বড় কার্যকরী পার্থক্যটি কল করব (যা অন্য উত্তরের মন্তব্যে উল্লেখ করা হয়েছে, তবে বুঝতে অসুবিধা হতে পারে) এটি খালি সংগ্রহের ক্ষেত্রে সঞ্চালিত হলে reduce
ব্যতিক্রম ঘটায়।
listOf<Int>().reduce { x, y -> x + y }
// java.lang.UnsupportedOperationException: Empty collection can't be reduced.
এটি কারণ .reduce
"ডেটা নেই" ইভেন্টে কোন মানটি ফিরবে তা জানেন না।
.fold
এটির সাথে বৈসাদৃশ্য করুন , যার জন্য আপনাকে "শুরুর মান" সরবরাহ করতে হবে যা খালি সংগ্রহের ক্ষেত্রে ডিফল্ট মান হবে:
val result = listOf<Int>().fold(0) { x, y -> x + y }
assertEquals(0, result)
সুতরাং, এমনকি যদি আপনি আপনার সংগ্রহটি আলাদা (অ-সম্পর্কিত) ধরণের (যা কেবল .fold
আপনাকে করতে দেয়) একক উপাদানে একত্রিত করতে না চান , তবে যদি আপনার প্রারম্ভিক সংগ্রহটি খালি থাকতে পারে তবে আপনাকে অবশ্যই সংগ্রহ সংগ্রহ করে দেখুন আকারটি প্রথমে এবং তারপরে .reduce
বা কেবল ব্যবহার করুন.fold
val collection: List<Int> = // collection of unknown size
val result1 = if (collection.isEmpty()) 0
else collection.reduce { x, y -> x + y }
val result2 = collection.fold(0) { x, y -> x + y }
assertEquals(result1, result2)