{"id":"l-sw-1-4","courseId":"swift-essentials","lang":"en","kind":"lesson","summary":"Write functions with clear argument labels and default values, then replace hand-written loops with closures passed to filter, map, reduce and sorted.","html":"<p>The <code dir=\"ltr\">for</code> loops from the last lesson work, but they make you read five lines to learn one fact, such as “the total spent on food”. Functions give a piece of logic a name. Closures let you hand a small piece of logic to someone else, like “keep the ones over 50”, and Swift’s collection methods are built around them. Together they turn most loops in Pocket Budget into one readable line.</p>\n<p>For the examples, here is a minimal expense type. You’ll learn what <code dir=\"ltr\">struct</code> really means in the next section; for now, read it as “a value with a title, an amount and a category”.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Expense.swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#953800;--shiki-dark:#FFA657\"> Foundation</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">struct</span><span style=\"color:#953800;--shiki-dark:#FFA657\"> Expense</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> title: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">String</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amount: Decimal</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> category: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">String</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">    Expense</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">title</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Groceries\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">amount</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">64.2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">category</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">),</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">    Expense</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">title</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bus pass\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">amount</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">45</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">category</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Transport\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">),</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">    Expense</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">title</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">amount</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">4.5</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">category</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">),</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">    Expense</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">title</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Concert\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">amount</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">80</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">category</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Fun\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">),</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]</span></span></code></pre></div>\n<h2 id=\"sec-1\" tabindex=\"-1\">Functions that read like sentences</h2>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">func</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> total</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">of</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses: [Expense], </span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">in</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> category: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">String</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">?</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> nil</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> Decimal {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    var</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sum: Decimal </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    for</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expense </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">in</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">where</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> category </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">==</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> nil</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ||</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expense.category </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">==</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> category {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">        sum </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expense.amount</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sum</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">total</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">of</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: expenses)                  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// 193.7</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">total</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">of</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: expenses, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">in</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)      </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// 68.7</span></span></code></pre></div>\n<p>Each parameter has two names. The <strong>argument label</strong> (<code dir=\"ltr\">of</code>, <code dir=\"ltr\">in</code>) is what callers write; the <strong>parameter name</strong> (<code dir=\"ltr\">expenses</code>, <code dir=\"ltr\">category</code>) is what the body uses. That split is why Swift call sites read like English: “total of expenses in Food”. The <code dir=\"ltr\">= nil</code> gives <code dir=\"ltr\">category</code> a default value, so callers can leave it out. Write <code dir=\"ltr\">_</code> as the label when it adds nothing, as in <code dir=\"ltr\">print(_:)</code>.</p>\n<p>The <code dir=\"ltr\">-&gt; Decimal</code> declares the return type. A function that returns nothing omits the arrow.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">Closures: functions without names</h2>\n<p>A closure is a block of code you can store in a constant or pass as an argument. Here is a closure that decides whether an expense is large:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> isLarge: (Expense) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Bool</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { expense </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">in</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    expense.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 50</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">isLarge</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(expenses[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])     </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// true</span></span></code></pre></div>\n<p>The type <code dir=\"ltr\">(Expense) -&gt; Bool</code> reads “takes an <code dir=\"ltr\">Expense</code>, returns a <code dir=\"ltr\">Bool</code>”. Parameters go before <code dir=\"ltr\">in</code>, the body after it. A single-expression body returns its value without writing <code dir=\"ltr\">return</code>.</p>\n<p>Now pass logic like that to <code dir=\"ltr\">filter</code>. These three lines are the same call, progressively shortened:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> large1 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">({ (</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">expense</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: Expense) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Bool</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> in</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expense.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 50</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">})</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> large2 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { expense </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">in</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expense.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 50</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> large3 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 50</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span></span></code></pre></div>\n<p>When a closure is the last argument, you can write it after the parentheses (<strong>trailing closure syntax</strong>) and drop empty parentheses entirely. Swift already knows the types from <code dir=\"ltr\">filter</code>’s signature, so you can drop those too. <code dir=\"ltr\">$0</code> is the first parameter, <code dir=\"ltr\">$1</code> the second.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">Tip</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>When to stop shortening</span></p>\n<p>Use <code dir=\"ltr\">$0</code> for one-line closures where the meaning is obvious. Once a closure spans several lines or takes two parameters you need to tell apart, name the parameters. Your future self is the main reader.</p>\n</aside>\n<h2 id=\"sec-3\" tabindex=\"-1\">filter, map, reduce, sorted</h2>\n<p>These four cover most of what you do with collections:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> food </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.category </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">==</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }        </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// keep matching expenses</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> titles </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> food.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">map</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.title }                           </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// [\"Groceries\", \"Coffee\"]</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> foodTotal </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> food.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">reduce</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> $1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.amount }            </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// 68.7</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> biggestFirst </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">sorted</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> $1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.amount } </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// Concert, Groceries, ...</span></span></code></pre></div>\n<p><code dir=\"ltr\">reduce</code> starts from an initial value (0) and folds each element into a running result: <code dir=\"ltr\">$0</code> is the total so far and <code dir=\"ltr\">$1</code> is the next expense. <code dir=\"ltr\">sorted(by:)</code> asks your closure “should <code dir=\"ltr\">$0</code> come before <code dir=\"ltr\">$1</code>?”.</p>\n<p>Chain them, and the pipeline reads in the order it runs:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"5\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> foodSpend </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    .</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.category </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">==</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    .</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">map</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\\.amount)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    .</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">reduce</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span></code></pre></div>\n<p><code dir=\"ltr\">\\.amount</code> is a <strong>key path</strong>, a shorthand for <code dir=\"ltr\">{ $0.amount }</code>, and <code dir=\"ltr\">+</code> is itself a function that takes two values and returns their sum, so you can pass it straight to <code dir=\"ltr\">reduce</code>.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 700 170\" role=\"img\" aria-labelledby=\"l-sw-1-4-t1\"><defs><marker id=\"arrow-l-sw-1-4-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-sw-1-4-t1\">Four expenses flow into filter, which keeps the two food expenses; map turns them into two amounts; reduce adds them into one total of 68.7.</title>\n  <rect class=\"d-box\" x=\"10\" y=\"50\" width=\"130\" height=\"70\" rx=\"10\"/>\n  <text class=\"d-label-strong\" x=\"75\" y=\"80\" text-anchor=\"middle\">4 expenses</text>\n  <text class=\"d-label-muted\" x=\"75\" y=\"102\" text-anchor=\"middle\">[Expense]</text>\n  <path class=\"d-arrow\" d=\"M140 85 L185 85\" marker-end=\"url(#arrow-l-sw-1-4-1)\"/>\n  <rect class=\"d-box-primary\" x=\"190\" y=\"50\" width=\"140\" height=\"70\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"260\" y=\"80\" text-anchor=\"middle\">filter</text>\n  <text class=\"d-label-muted\" x=\"260\" y=\"102\" text-anchor=\"middle\">2 food items</text>\n  <path class=\"d-arrow\" d=\"M330 85 L375 85\" marker-end=\"url(#arrow-l-sw-1-4-1)\"/>\n  <rect class=\"d-box-accent\" x=\"380\" y=\"50\" width=\"140\" height=\"70\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"450\" y=\"80\" text-anchor=\"middle\">map(\\.amount)</text>\n  <text class=\"d-label-muted\" x=\"450\" y=\"102\" text-anchor=\"middle\">[64.2, 4.5]</text>\n  <path class=\"d-arrow\" d=\"M520 85 L565 85\" marker-end=\"url(#arrow-l-sw-1-4-1)\"/>\n  <rect class=\"d-box-success\" x=\"570\" y=\"50\" width=\"120\" height=\"70\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"630\" y=\"80\" text-anchor=\"middle\">reduce</text>\n  <text class=\"d-label-muted\" x=\"630\" y=\"102\" text-anchor=\"middle\">68.7</text>\n  <text class=\"d-label-muted\" x=\"350\" y=\"155\" text-anchor=\"middle\">Each step returns a new value; the original array never changes</text>\n</svg><figcaption>filter, map and reduce as a pipeline</figcaption></figure>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">Common mistake</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Calling sorted and ignoring the result</span></p>\n<p><code dir=\"ltr\">expenses.sorted { … }</code> on a line by itself does nothing useful: it returns a new array and throws it away, and Xcode warns “result of call to ‘sorted(by:)’ is unused”. Assign the result, or call <code dir=\"ltr\">sort(by:)</code> on a <code dir=\"ltr\">var</code> array to sort it in place.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">Closures capture their surroundings</h2>\n<p>A closure can use variables from the scope where it was created, and it keeps them alive:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"6\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">func</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> makeLimitCheck</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">limit</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: Decimal) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (Decimal) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Bool</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">in</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> limit }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> overFoodLimit </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> makeLimitCheck</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">limit</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">60</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">overFoodLimit</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">64.2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)     </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// true</span></span></code></pre></div>\n<p><code dir=\"ltr\">makeLimitCheck</code> has returned, yet the closure still knows <code dir=\"ltr\">limit</code> is 60. When a function stores a closure parameter to call later, instead of calling it before returning, Swift makes you mark that parameter <code dir=\"ltr\">@escaping</code>. The keyword is a warning label for readers: this closure outlives the call, so whatever it captures stays alive too.</p>\n<p>This <strong>capturing</strong> is what lets SwiftUI buttons run code that refers to your view’s data long after the view was built. It has one sharp edge, a reference cycle when a class and a closure capture each other, which you’ll meet with classes in the next lesson.</p>\n<p>You can now name logic, pass it around and replace loops with pipelines. That finishes the core language. The next section is about modelling: deciding whether Pocket Budget’s data should be structs, classes or enums, and why that choice changes how your app behaves.</p>\n","toc":[{"id":"sec-1","text":"Functions that read like sentences","level":2},{"id":"sec-2","text":"Closures: functions without names","level":2},{"id":"sec-3","text":"filter, map, reduce, sorted","level":2},{"id":"sec-4","text":"Closures capture their surroundings","level":2}],"takeaways":["Argument labels make call sites read like sentences; use <code dir=\"ltr\">_</code> only when the label would add nothing.","A closure is a function without a name, and trailing closure syntax lets you write it after the call’s parentheses.","<code dir=\"ltr\">filter</code> keeps elements, <code dir=\"ltr\">map</code> transforms them, <code dir=\"ltr\">reduce</code> combines them into one value, and <code dir=\"ltr\">sorted(by:)</code> returns a new ordered array.","A closure captures the variables it uses, so it can carry context such as a limit to wherever it’s called later."],"further":[{"title":"Functions","url":"https://docs.swift.org/swift-book/documentation/the-swift-programming-language/functions/"},{"title":"Closures","url":"https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/"}],"quiz":[{"q":"<p>Given <code dir=\"ltr\">func total(of expenses: [Expense], in category: String? = nil) -&gt; Decimal</code>, which call compiles?</p>","options":[{"text":"<code dir=\"ltr\">total(expenses, &quot;Food&quot;)</code>","why":"Both parameters have argument labels, so the call must use them."},{"text":"<code dir=\"ltr\">total(expenses: expenses)</code>","why":"<code dir=\"ltr\">expenses</code> is the parameter name used inside the function. Callers use the label <code dir=\"ltr\">of</code>."},{"text":"<code dir=\"ltr\">total(of: expenses)</code>","why":"Correct. The second parameter has a default value, so you can leave it out."}],"answer":2},{"q":"<p>What does <code dir=\"ltr\">[3, 8, 12].map { $0 * 2 }.filter { $0 &gt; 10 }</code> produce?</p>","options":[{"text":"<code dir=\"ltr\">[16, 24]</code>","why":"Correct. <code dir=\"ltr\">map</code> doubles every number to <code dir=\"ltr\">[6, 16, 24]</code>, then <code dir=\"ltr\">filter</code> keeps those above 10."},{"text":"<code dir=\"ltr\">[24]</code>","why":"That would be filtering before mapping (<code dir=\"ltr\">12</code> is the only value above 10). The chain runs left to right."},{"text":"<code dir=\"ltr\">[6, 16, 24]</code>","why":"That’s the result after <code dir=\"ltr\">map</code> only; <code dir=\"ltr\">filter</code> still has to remove 6."},{"text":"<code dir=\"ltr\">40</code>","why":"A single combined value is what <code dir=\"ltr\">reduce</code> produces. <code dir=\"ltr\">map</code> and <code dir=\"ltr\">filter</code> both return arrays."}],"answer":0},{"q":"<p>You write <code dir=\"ltr\">expenses.sorted { $0.amount &gt; $1.amount }</code> on its own line and nothing changes. Why?</p>","options":[{"text":"The closure compares the wrong way round.","why":"The comparison is fine (largest first). The result is the problem."},{"text":"<code dir=\"ltr\">sorted</code> returns a new array, and the code throws that result away.","why":"Correct. Assign it (<code dir=\"ltr\">let biggestFirst = …</code>) or call <code dir=\"ltr\">sort</code> on a <code dir=\"ltr\">var</code> to sort in place. Xcode warns about the unused result."},{"text":"Closures can’t read properties like <code dir=\"ltr\">amount</code>.","why":"Closures can read anything in scope, including properties of their parameters."}],"answer":1},{"q":"<p><code dir=\"ltr\">let check = makeLimitCheck(limit: 60)</code> returns a closure <code dir=\"ltr\">{ amount in amount &gt; limit }</code>. What does <code dir=\"ltr\">check(64)</code> return, long after <code dir=\"ltr\">makeLimitCheck</code> finished?</p>","options":[{"text":"It doesn’t compile, because <code dir=\"ltr\">limit</code> no longer exists.","why":"The closure captured <code dir=\"ltr\">limit</code>, so it lives as long as the closure does."},{"text":"<code dir=\"ltr\">false</code>, because captured values reset to zero.","why":"Captures keep their values; nothing resets."},{"text":"<code dir=\"ltr\">true</code>","why":"Correct. The closure captured <code dir=\"ltr\">limit</code> as 60, and 64 is greater than 60."}],"answer":2}],"exercise":{"kind":"fill","language":"swift","template":"// expenses: [Expense], each with title, amount and category\nlet large = expenses.{{0}} { $0.amount > 50 }\nlet titles = large.{{1}} { $0.title }\nlet spent = expenses.{{2}}(0) { $0 + $1.amount }\nlet biggestFirst = expenses.sorted { $0.amount {{3}} $1.amount }","blanks":[{"answers":["filter"]},{"answers":["map"]},{"answers":["reduce"]},{"answers":[">"]}],"title":"Replace the loops with closures","prompt":"<p>Pocket Budget’s summary screen needs four values. Fill each blank so that <code dir=\"ltr\">large</code> holds the expenses over 50, <code dir=\"ltr\">titles</code> holds their titles, <code dir=\"ltr\">spent</code> is the total of all amounts, and <code dir=\"ltr\">biggestFirst</code> lists every expense from the largest amount to the smallest.</p>\n","hints":["Each of the first three blanks is the name of a collection method from this lesson.","<code dir=\"ltr\">reduce</code> takes a starting value and a closure that combines the running total (<code dir=\"ltr\">$0</code>) with the next element (<code dir=\"ltr\">$1</code>).","<code dir=\"ltr\">sorted(by:)</code> asks “should <code dir=\"ltr\">$0</code> come before <code dir=\"ltr\">$1</code>?”. For largest first, the answer is yes when <code dir=\"ltr\">$0</code> is bigger."],"explanation":"<p><code dir=\"ltr\">filter</code> keeps elements for which the closure returns <code dir=\"ltr\">true</code>, <code dir=\"ltr\">map</code> turns each expense into its title, and <code dir=\"ltr\">reduce(0)</code> folds every amount into one total. <code dir=\"ltr\">sorted</code> puts <code dir=\"ltr\">$0</code> first whenever the closure returns <code dir=\"ltr\">true</code>, so <code dir=\"ltr\">$0.amount &gt; $1.amount</code> gives descending order; <code dir=\"ltr\">&lt;</code> would put the cheapest first.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> large </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 50</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> titles </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> large.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">map</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.title }</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> spent </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">reduce</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> $1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.amount }</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> biggestFirst </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">sorted</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> $1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.amount }</span></span></code></pre></div>\n","checkLabels":{}},"words":679,"readMinutes":3}