Lambdas and Iterators

Back

Loading concept...

๐Ÿš€ Lambdas & Iterators: Your Magic Helpers in C#

Imagine you have a tiny robot friend who can do ONE thing really well, and you can tell it what to do in just one sentence. Thatโ€™s a Lambda! And imagine a patient librarian who hands you ONE book at a time from a huge pile. Thatโ€™s an Iterator!


๐ŸŽญ The Story: Meet Your Two Magic Helpers

Once upon a time, you had a big toy box with hundreds of toys. You needed two helpers:

  1. Lambda the Quick Helper - Does small tasks instantly when you ask
  2. Iterator the Patient Helper - Hands you toys one by one, never all at once

Letโ€™s meet them!


๐Ÿ“– Chapter 1: Lambda Expressions

What is a Lambda?

Think of a lambda like giving someone a very short instruction without needing to explain everything.

Normal way (long):

// Like writing a full letter
public int AddFive(int number)
{
    return number + 5;
}

Lambda way (short and sweet):

// Like sending a quick text
x => x + 5

The => is called the โ€œarrowโ€ and it means โ€œgoes toโ€ or โ€œdoes this.โ€

How to Read It

x => x + 5
  • x = the thing Iโ€™m getting
  • => = โ€œgoes toโ€ or โ€œturns intoโ€
  • x + 5 = the result

It reads: โ€œx goes to x plus 5โ€

Simple Examples

// Add two numbers
(a, b) => a + b

// Check if number is big
n => n > 10

// Say hello
name => quot;Hello, {name}!"

Using Lambdas with Lists

List<int> numbers = new List<int>
    { 1, 2, 3, 4, 5 };

// Find all numbers bigger than 2
var bigNumbers = numbers
    .Where(n => n > 2);
// Result: 3, 4, 5

// Double each number
var doubled = numbers
    .Select(n => n * 2);
// Result: 2, 4, 6, 8, 10

๐Ÿ“– Chapter 2: Closures

What is a Closure?

A closure is when a lambda remembers something from outside itself. Like a kid who remembers their parentโ€™s name even when theyโ€™re at school!

graph TD A["๐Ÿ  Outside Variable"] --> B["๐Ÿ“ฆ Lambda Created"] B --> C["๐Ÿ”’ Closure Captures It"] C --> D["๐Ÿ“ž Lambda Called Later"] D --> E["โœจ Still Remembers!"]

Example: The Counting Toy

int toyCount = 0;

Action addToy = () =>
{
    toyCount++;  // Remembers toyCount!
    Console.WriteLine(quot;Toys: {toyCount}");
};

addToy(); // Toys: 1
addToy(); // Toys: 2
addToy(); // Toys: 3

The lambda captured toyCount and remembers it every time!

Why Closures are Magical

Func<int, int> MakeMultiplier(int by)
{
    // 'by' gets captured!
    return x => x * by;
}

var double = MakeMultiplier(2);
var triple = MakeMultiplier(3);

Console.WriteLine(double(5)); // 10
Console.WriteLine(triple(5)); // 15

Each lambda remembers its own by value!


๐Ÿ“– Chapter 3: The Yield Keyword

What is Yield?

Imagine youโ€™re reading a HUGE storybook. yield is like reading one page at a time instead of reading the whole book before telling anyone about it.

graph TD A["๐Ÿ“š Big Collection"] --> B["yield return"] B --> C["๐Ÿ“„ Give One Item"] C --> D["โธ๏ธ Pause Here"] D --> E["๐Ÿ“ž Asked for More?"] E -->|Yes| B E -->|No| F["๐Ÿ›‘ Stop"]

Without Yield (Get Everything First)

List<int> GetNumbers()
{
    List<int> result = new List<int>();
    result.Add(1);
    result.Add(2);
    result.Add(3);
    return result; // All at once!
}

With Yield (Give One at a Time)

IEnumerable<int> GetNumbers()
{
    yield return 1; // Give 1, pause
    yield return 2; // Give 2, pause
    yield return 3; // Give 3, done
}

Why Yield is Amazing

IEnumerable<int> CountForever()
{
    int number = 1;
    while (true)
    {
        yield return number;
        number++;
    }
}

// Only takes what we need!
foreach (int n in CountForever().Take(5))
{
    Console.WriteLine(n);
}
// Prints: 1, 2, 3, 4, 5

We created INFINITE numbers but only used 5!


๐Ÿ“– Chapter 4: Custom Iterators

What is an Iterator?

An iterator is a helper that knows how to walk through your collection, one step at a time.

Making Your Own Iterator

class ToyBox : IEnumerable<string>
{
    string[] toys = { "Ball", "Car", "Doll" };

    public IEnumerator<string> GetEnumerator()
    {
        foreach (string toy in toys)
        {
            yield return toy;
        }
    }

    // Required for interface
    IEnumerator IEnumerable.GetEnumerator()
        => GetEnumerator();
}

Now you can use it like this:

var box = new ToyBox();
foreach (string toy in box)
{
    Console.WriteLine(toy);
}
// Ball, Car, Doll

Custom Logic in Iterators

IEnumerable<int> EvenNumbers(int max)
{
    for (int i = 2; i <= max; i += 2)
    {
        yield return i;
    }
}

foreach (int n in EvenNumbers(10))
{
    Console.WriteLine(n);
}
// Prints: 2, 4, 6, 8, 10

๐Ÿ“– Chapter 5: Iterator Patterns

Pattern 1: Filtering

Only give items that match a rule:

IEnumerable<T> Filter<T>(
    IEnumerable<T> items,
    Func<T, bool> rule)
{
    foreach (var item in items)
    {
        if (rule(item))
            yield return item;
    }
}

// Usage
var bigNumbers = Filter(
    new[] { 1, 5, 10, 15 },
    n => n > 7);
// Result: 10, 15

Pattern 2: Transforming

Change each item as you give it:

IEnumerable<R> Transform<T, R>(
    IEnumerable<T> items,
    Func<T, R> change)
{
    foreach (var item in items)
    {
        yield return change(item);
    }
}

// Usage
var doubled = Transform(
    new[] { 1, 2, 3 },
    n => n * 2);
// Result: 2, 4, 6

Pattern 3: Pagination

Give items in chunks:

IEnumerable<List<T>> GetPages<T>(
    IEnumerable<T> items,
    int pageSize)
{
    List<T> page = new List<T>();

    foreach (var item in items)
    {
        page.Add(item);
        if (page.Count == pageSize)
        {
            yield return page;
            page = new List<T>();
        }
    }

    if (page.Count > 0)
        yield return page;
}

Pattern 4: Lazy Evaluation Chain

var result = numbers
    .Where(n => n > 5)     // Iterator 1
    .Select(n => n * 2)    // Iterator 2
    .Take(10);             // Iterator 3

// Nothing happens until...
foreach (var n in result) // NOW it runs!
{
    Console.WriteLine(n);
}

Each step is lazy - it only works when you ask for values!


๐ŸŽฏ Quick Summary

Concept What It Does One-Liner Example
Lambda Short function x => x * 2
Closure Lambda remembers outside stuff () => count++
Yield Give one item, pause yield return item;
Iterator Walk through collection IEnumerable<T>
Pattern Reusable iterator recipe Filter, Transform, Page

๐ŸŒŸ You Did It!

You now understand the magic helpers in C#:

  • Lambdas give you quick, one-line functions
  • Closures let lambdas remember things
  • Yield serves items one at a time
  • Iterators let you walk through any collection
  • Iterator Patterns solve common problems elegantly

These tools make your code shorter, smarter, and more memory-friendly!

๐ŸŽ‰ Go build something amazing!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.