Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
April 12, 2018 Using iteration / method chaining / etc on multi-dimensional arrays | ||||
---|---|---|---|---|
| ||||
I googled but couldn't find any clear solution. I've got a 2-D array of strings read from a text file I parsed. So it's like 0 1 15 0 0 2 12 1 0 0 ... 0 1 0 10 0 They come in with spaces, so I join into an array between them. But then the last ones have a newline \n on the end, which explodes the to! type conversion. If it was a single array, I could simply do: string [25] test; test.each((ref n) => n.stripRight()); But how do you do that when it's a 2-D array? I'm looking not just for this case, but the generate case of iterating / applying filters to 2-D arrays. Thanks. |
April 12, 2018 Re: Using iteration / method chaining / etc on multi-dimensional arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | On Thursday, 12 April 2018 at 15:38:34 UTC, Chris Katko wrote:
> I googled but couldn't find any clear solution.
>
> I've got a 2-D array of strings read from a text file I parsed. So it's like
>
> 0 1 15 0 0
> 2 12 1 0 0
> ...
> 0 1 0 10 0
>
> They come in with spaces, so I join into an array between them. But then the last ones have a newline \n on the end, which explodes the to! type conversion.
>
> If it was a single array, I could simply do:
>
> string [25] test;
>
> test.each((ref n) => n.stripRight());
>
> But how do you do that when it's a 2-D array?
>
> I'm looking not just for this case, but the generate case of iterating / applying filters to 2-D arrays.
>
> Thanks.
I think something like this would work:
test.each((ref s) => s.each((ref n) => n.stripRight()));
Essentially, get each 1D array from the 2D array, and then apply the algorithms on that. There's probably a better way though
|
April 12, 2018 Re: Using iteration / method chaining / etc on multi-dimensional arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | On Thursday, 12 April 2018 at 15:38:34 UTC, Chris Katko wrote: > I googled but couldn't find any clear solution. > > I've got a 2-D array of strings read from a text file I parsed. So it's like > > 0 1 15 0 0 > 2 12 1 0 0 > ... > 0 1 0 10 0 > > They come in with spaces, so I join into an array between them. But then the last ones have a newline \n on the end, which explodes the to! type conversion. > > If it was a single array, I could simply do: > > string [25] test; > > test.each((ref n) => n.stripRight()); > > But how do you do that when it's a 2-D array? > > I'm looking not just for this case, but the generate case of iterating / applying filters to 2-D arrays. > > Thanks. Use mir for multi-dimensional arrays: https://github.com/libmir/mir-algorithm It used to be part of phobos, but was removed as phobos's release cycle is too stable and dub gives much more flexibility. |
April 12, 2018 Re: Using iteration / method chaining / etc on multi-dimensional arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uknown | On Thursday, 12 April 2018 at 15:47:14 UTC, Uknown wrote: > On Thursday, 12 April 2018 at 15:38:34 UTC, Chris Katko wrote: >> I googled but couldn't find any clear solution. >> >> I've got a 2-D array of strings read from a text file I parsed. So it's like >> >> 0 1 15 0 0 >> 2 12 1 0 0 >> ... >> 0 1 0 10 0 >> >> They come in with spaces, so I join into an array between them. But then the last ones have a newline \n on the end, which explodes the to! type conversion. >> >> If it was a single array, I could simply do: >> >> string [25] test; >> >> test.each((ref n) => n.stripRight()); >> >> But how do you do that when it's a 2-D array? >> >> I'm looking not just for this case, but the generate case of iterating / applying filters to 2-D arrays. >> >> Thanks. > > I think something like this would work: > > test.each((ref s) => s.each((ref n) => n.stripRight())); > > Essentially, get each 1D array from the 2D array, and then apply the algorithms on that. There's probably a better way though But each doesn't return anything, it mutates, right? I think that's the problem I ran into with my attempt. With your code, I get an error about void: string []x = split(file.readln.idup, " "); x.each((ref s) => s.each((ref n) => n.stripRight())); extra.d(2493): Error: template std.algorithm.iteration.each cannot deduce function from argument types !()(string[], void), candidates are: /usr/include/dmd/phobos/std/algorithm/iteration.d(864): std.algorithm.iteration.each(alias pred = "a") extra.d(2499): Error: template std.algorithm.mutation.stripRight cannot deduce function from argument types !()(string), candidates are: /usr/include/dmd/phobos/std/algorithm/mutation.d(2363): std.algorithm.mutation.stripRight(Range, E)(Range range, E element) if (isBidirectionalRange!Range && is(typeof(range.back == element) : bool)) /usr/include/dmd/phobos/std/algorithm/mutation.d(2375): std.algorithm.mutation.stripRight(alias pred, Range)(Range range) if (isBidirectionalRange!Range && is(typeof(pred(range.back)) : bool)) extra.d(2500): Error: template std.algorithm.mutation.stripRight cannot deduce function from argument types !()(string), candidates are: /usr/include/dmd/phobos/std/algorithm/mutation.d(2363): std.algorithm.mutation.stripRight(Range, E)(Range range, E element) if (isBidirectionalRange!Range && is(typeof(range.back == element) : bool)) /usr/include/dmd/phobos/std/algorithm/mutation.d(2375): std.algorithm.mutation.stripRight(alias pred, Range)(Range range) if (isBidirectionalRange!Range && is(typeof(pred(range.back)) : bool)) |
April 12, 2018 Re: Using iteration / method chaining / etc on multi-dimensional arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | Wait, that might not be the error. |
April 12, 2018 Re: Using iteration / method chaining / etc on multi-dimensional arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | On Thursday, 12 April 2018 at 20:37:49 UTC, Chris Katko wrote: > Wait, that might not be the error. Just the top one. This one: extra.d(2493): Error: template std.algorithm.iteration.each cannot deduce function from argument types !()(string[], void), candidates are: /usr/include/dmd/phobos/std/algorithm/iteration.d(864): std.algorithm.iteration.each(alias pred = "a") |
April 12, 2018 Re: Using iteration / method chaining / etc on multi-dimensional arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | On Thursday, 12 April 2018 at 20:34:40 UTC, Chris Katko wrote:
>
> But each doesn't return anything, it mutates, right? I think that's the problem I ran into with my attempt. With your code, I get an error about void:
>
> string []x = split(file.readln.idup, " ");
> x.each((ref s) => s.each((ref n) => n.stripRight()));
You need to put an exclamation point after 'each' to pass the function as a template parameter:
x.each!((ref s) => s.each!((ref n) => n.stripRight()));
|
April 12, 2018 Re: Using iteration / method chaining / etc on multi-dimensional arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On Thursday, 12 April 2018 at 21:17:30 UTC, Paul Backus wrote: > On Thursday, 12 April 2018 at 20:34:40 UTC, Chris Katko wrote: >> >> But each doesn't return anything, it mutates, right? I think that's the problem I ran into with my attempt. With your code, I get an error about void: >> >> string []x = split(file.readln.idup, " "); >> x.each((ref s) => s.each((ref n) => n.stripRight())); > > You need to put an exclamation point after 'each' to pass the function as a template parameter: > > x.each!((ref s) => s.each!((ref n) => n.stripRight())); DOH. But now I'm here: extra.d(2493): Error: template extra.map_t.load_map2.each!((ref s) => s.each!((ref n) => n.stripRight())).each cannot deduce function from argument types !()(string[]), candidates are: /usr/include/dmd/phobos/std/algorithm/iteration.d(899): extra.map_t.load_map2.each!((ref s) => s.each!((ref n) => n.stripRight())).each(Range)(Range r) if (!isForeachIterable!Range && (isRangeIterable!Range || __traits(compiles, typeof(r.front).length))) /usr/include/dmd/phobos/std/algorithm/iteration.d(934): extra.map_t.load_map2.each!((ref s) => s.each!((ref n) => n.stripRight())).each(Iterable)(auto ref Iterable r) if (isForeachIterable!Iterable || __traits(compiles, Parameters!(Parameters!(r.opApply)))) From: string []x = split(file.readln.idup, " "); import std.algorithm; x.each!((ref s) => s.each!((ref n) => n.stripRight())); Looks like it can't tell if it's a Range or... an auto ref Iterable? |
April 12, 2018 Re: Using iteration / method chaining / etc on multi-dimensional arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | On 04/12/2018 02:22 PM, Chris Katko wrote: > On Thursday, 12 April 2018 at 21:17:30 UTC, Paul Backus wrote: >> On Thursday, 12 April 2018 at 20:34:40 UTC, Chris Katko wrote: >>> >>> But each doesn't return anything, it mutates, right? I think that's the problem I ran into with my attempt. With your code, I get an error about void: >>> >>> string []x = split(file.readln.idup, " "); >>> x.each((ref s) => s.each((ref n) => n.stripRight())); >> >> You need to put an exclamation point after 'each' to pass the function as a template parameter: >> >> x.each!((ref s) => s.each!((ref n) => n.stripRight())); > > DOH. > > But now I'm here: > > extra.d(2493): Error: template extra.map_t.load_map2.each!((ref s) => s.each!((ref n) => n.stripRight())).each cannot deduce function from argument types !()(string[]), candidates are: > > /usr/include/dmd/phobos/std/algorithm/iteration.d(899): extra.map_t.load_map2.each!((ref s) => s.each!((ref n) => n.stripRight())).each(Range)(Range r) if (!isForeachIterable!Range && (isRangeIterable!Range || __traits(compiles, typeof(r.front).length))) > > /usr/include/dmd/phobos/std/algorithm/iteration.d(934): extra.map_t.load_map2.each!((ref s) => s.each!((ref n) => n.stripRight())).each(Iterable)(auto ref Iterable r) if (isForeachIterable!Iterable || __traits(compiles, Parameters!(Parameters!(r.opApply)))) > > > From: > > string []x = split(file.readln.idup, " "); > import std.algorithm; > x.each!((ref s) => s.each!((ref n) => n.stripRight())); > > Looks like it can't tell if it's a Range or... an auto ref Iterable? Assuming the file "2darray" includes 0 1 15 0 0 2 12 1 0 0 0 1 0 10 0 the following program produces a range of ranges that produce the intended integer values: import std.stdio; import std.algorithm; import std.conv; void main() { auto file = File("2darray"); auto r = file.byLine.map!(l => l.splitter.map!(to!int)); writefln("%(%s\n%)", r); } The output is [0, 1, 15, 0, 0] [2, 12, 1, 0, 0] [0, 1, 0, 10, 0] If you want to produce an actual 2d array, you can add two .array calls at that chain: import std.range : array; auto r = file.byLine.map!(l => l.splitter.map!(to!int).array).array; Ali |
Copyright © 1999-2021 by the D Language Foundation