Recent Changes - Search:

Oktatás

* Programozás 1
  + feladatsor
  + GitHub oldal

* Szkriptnyelvek
  + feladatsor
  + quick link

Teaching

* Programming 1 (BI)
  ◇ exercises
  ◇ quick link

teaching assets


Félévek

* 2025/26/2
* archívum


Linkek

* kalendárium
   - munkaszüneti napok '20
* tételsorok
* jegyzetek
* szakdolgozat / PhD
* ösztöndíjak
* certificates
* C lang.
* C++
* C#
* Clojure
* D lang.
* Java
* Nim
* Nim2
* Scala


[ edit | logout ]
[ sandbox | passwd ]

filter and map operations

Let's see the filter and map operations. In Python, we use list comprehensions.

(1) filter, map
def main():
    li = [1, 8, 2, 5, 9, 0, 7]

    small = [x for x in li if x < 5]
    print(small)  # [1, 2, 0]

    double = [2 * x for x in li]
    print(double)  # [2, 16, 4, 10, 18, 0, 14]

    both = [2 * x for x in li if x < 5]
    print(both)  # [2, 4, 0]
import std/sequtils    # map, filter
import std/sugar       # => operator

proc main() =
  let li = @[1, 8, 2, 5, 9, 0, 7]

  let small = li.filter(x => x < 5)
  echo small  # @[1, 2, 0]

  let double = li.map(x => 2 * x)
  echo double  # @[2, 16, 4, 10, 18, 0, 14]

  let both = li.filter(x => x < 5).map(x => 2 * x)
  echo both  # @[2, 4, 0]

Again, when we write li.map(…), that's actually UFCS magic.

Notice that the result of filter() and map() is a new sequence. Every time you call these functions, a new sequence is created. When you work with huge sequences and you chain together several filter and map calls, it might be memory-heavy. See the zero_functional library if you need lazy evaluation.

"=>" is a macro, actually. It's syntactic sugar for anonymous procedures.

Can we simplify it?

Sure :) Nim has two useful templates: mapIt and filterIt. We'll see templates later. At the moment, it's enough to see how to use it:

(2) filterIt, mapIt
# same Python code
import std/sequtils    # toSeq(iter), map, filter
# std/sugar is not needed

proc main() =
  let li = @[1, 8, 2, 5, 9, 0, 7]

  let small = li.filterIt(it < 5)
  echo small  # @[1, 2, 0]

  let double = li.mapIt(2 * it)
  echo double  # @[2, 16, 4, 10, 18, 0, 14]

  let both = li.filterIt(it < 5).mapIt(2 * it)
  echo both  # @[2, 4, 0]

As you can see, it means the current element.

Using the collect macro

Nim has a macro too, called collect that can do something similar. What is a macro? We'll see later :)

(3) collect
# same Python code
# std/sequtils is not needed
import std/sugar  # collect

proc main() =
  let li = @[1, 8, 2, 5, 9, 0, 7]

  let small = collect:
    for x in li:
      if x < 5:
        x
  echo small  # @[1, 2, 0]

  let double = collect:
    for x in li:
      2 * x
  echo double  # @[2, 16, 4, 10, 18, 0, 14]

  let both = collect:
    for x in li:
      if x < 5:
        2 * x
  echo both  # @[2, 4, 0]

Here, when you use both the filter and map operations (last example), then no intermediate sequence is built. Only the resulting sequence is constructed.

Cloud City

  

Blogjaim, hobbi projektjeim

* The Ubuntu Incident
* Python Adventures
* @GitHub
* heroku
* extra
* haladó Python
* YouTube listák


Debrecen | la France


[ edit ]

Edit - History - Print *** Report - Recent Changes - Search
Page last modified on 2026 April 10, 12:22