Home > Net >  In Julia, why does a string sometimes present as an iterator of characters but not a collection?
In Julia, why does a string sometimes present as an iterator of characters but not a collection?

Time:12-13

In Julia, these examples of a string being treated as an iterator (delivering characters) work:

number = "1234"
notnumber = "123z"
isgood = all(isdigit, number) # true
isobad = all(isdigit, notnumber) # false
isgood = mapreduce(isdigit, &, number) # also true
isbad = mapreduce(isdigit, &, notnumber) # also false
myhex = mapreduce(codepoint, &, number) # 0x00000030
avector = map(codecode, collect(number)) 

but this does not work, despite isdigit() and codepoint() having a very similar signatures:

avector = map(codepoint, number) # causes error

Why is it sometimes necessary to use collect() on the string? If the answer is because all() and mapreduce() take iter and map() takes collection, please explain the distinction?

Is using collect() with map() wrong, because it leads to longer execution times or greater memory usage?

CodePudding user response:

The reason is that map and filter have a special implementation for AbstractString. They iterate a string and return a string. Therefore, in map it is required that the function you pass returns AbstractChar. Here is an example:

julia> x = "a12b3"
"a12b3"

julia> map(uppercase, x)
"A12B3"

and a similar example with filter:

julia> filter(isdigit, x)
"123"

Now if you do not want not to have a string as a result of map but rather a vector then use collect (which is expensive as you note), or use a comprehension:

julia> [codepoint(c) for c in x]
5-element Vector{UInt32}:
 0x00000061
 0x00000031
 0x00000032
 0x00000062
 0x00000033
  • Related