22

Since Nim shares a lot of features with Python, i would not be surprised if it implements Python's list comprehension too:

string = "Hello 12345 World"
numbers = [x for x in string if x.isdigit()]
# ['1', '2', '3', '4', '5']

Is this actually possible in Nim? If not, could be implemented with templates/macros ?

Grzegorz Adam Hankiewicz
  • 7,349
  • 1
  • 36
  • 78
Arrrrrrr
  • 802
  • 6
  • 13

4 Answers4

20

UPDATE: List comprehension has been deprecated since version 0.19.9 (Source). A good alternative is to use the new sugar.collect macro.

Another update: As of 2023, list comprehension has been removed.


Outdated original answer

List comprehension is implemented in Nim in the sugar package (i.e., you have to import sugar). It is implemented as a macro called lc and allows to write list comprehensions like this:

lc[x | (x <- 1..10, x mod 2 == 0), int]

lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z), tuple[a,b,c: int]]

Note that the macro requires to specify the type of the elements.

bluenote10
  • 23,414
  • 14
  • 122
  • 178
  • @Downvoter: Surprised to get downvotes here. Is it just because the other answer has been updated or is there something wrong with my answer? – bluenote10 Apr 28 '15 at 08:35
  • Your answer is right, and since you were the first that commented on future module, i'll mark yours as the correct. – Arrrrrrr Apr 28 '15 at 16:11
  • 1
    List comprehensions are deprecated since version 0.19.9. – danlei Aug 17 '19 at 16:26
  • 1
    For a library-based solution check out https://github.com/alehander42/comprehension – Aleksi Aug 27 '19 at 09:04
  • 2
    the prefered way of doing this is with the collect macro in sugar https://nim-lang.org/docs/sugar.html#collect.m%2Cuntyped%2Cuntyped – zidsal Feb 06 '21 at 22:19
  • 1
    @daten-kieker That information that the answer is outdated is written in the first paragraph of the answer. I'll try to make it even more obvious... – bluenote10 Jun 17 '23 at 10:59
  • @bluenote10 - sorry, my bad. Too focused on the code snippet, I guess. I'll delete my comment. – daten-kieker Jun 17 '23 at 14:19
9

According to rosettacode, Nim has no list comprehensions, but they can be created through metaprogramming.

[EDIT]

As pointed out by bluenote10, list comprehensions are now part of the future module:

import future
var str = "Hello 12345 World"
echo lc[x | (x <- str, ord(x) - ord('0') in 0..9),  char]

The above snippet yields @[1, 2, 3, 4, 5]

xbello
  • 7,223
  • 3
  • 28
  • 41
EvenLisle
  • 4,672
  • 3
  • 24
  • 47
7

Original

import sugar

let items = collect(newSeq):
  for x in @[1, 2, 3]: x * 2

echo items

outputs @[2, 4, 6]

Updated to answer question

import sugar
import sequtils
import strutils

let numbers = collect: # collect from suger
  for x in "Hello 12345 World".toSeq: # toSeq from sequtils
    if x.isDigit: # isDigit from strutils
      x

echo numbers

outputs @['1', '2', '3', '4', '5']

dotfelixb
  • 146
  • 1
  • 3
2

Nim translation of your code:

import sugar, strutils
var str = "Hello 12345 World"
echo collect(for s in str:
  if s.isDigit(): s)
Victor Yan
  • 3,339
  • 2
  • 28
  • 28