digitalmars.D.learn - Splitting a range into a range of tuples
- Adam (21/21) Jun 01 2015 Hi,
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (27/45) Jun 01 2015 With no promises on performance and with a bonus mind-blowing format
- Adam (15/25) Jun 01 2015 Thanks for the reply. I'm a bit confused by the splitter followed
- Adam (19/24) Jun 01 2015 Alright! I got what I wanted. Posting here for any fellow noobs
- Dennis Ritchie (20/25) Jun 01 2015 I can offer this option:
Hi, I have a string of pairs of integers, where pairs are delimited from each other by commas, and members of the pair are delimited by a space. I'd like to end up with something like a range of 2-tuples, which I can then sort with a lambda. I'm running into problems trying to do this, after splitting on commas: Tuple!(int,int) coord = to!(int[])(splitter(pairString," ").array[]); ...which may not even be a good idea, I don't know. I've been following D for a long time, but this is the first time I've tried to actually use it; this seems like the kind of thing that should take just a few lines, if only I knew the libraries and range concepts well enough. To be clear, this is what I have: "192 14, 301 3, 578 0, 0 17" ...and this is what I want: [(578,0),(301,3),(192,14),(0,17)] What's the best way to do this? Should I be using map!() somewhere? Thanks, Adam
Jun 01 2015
On 06/01/2015 03:31 PM, Adam wrote:Hi, I have a string of pairs of integers, where pairs are delimited from each other by commas, and members of the pair are delimited by a space. I'd like to end up with something like a range of 2-tuples, which I can then sort with a lambda. I'm running into problems trying to do this, after splitting on commas: Tuple!(int,int) coord = to!(int[])(splitter(pairString," ").array[]); ...which may not even be a good idea, I don't know. I've been following D for a long time, but this is the first time I've tried to actually use it; this seems like the kind of thing that should take just a few lines, if only I knew the libraries and range concepts well enough. To be clear, this is what I have: "192 14, 301 3, 578 0, 0 17" ...and this is what I want: [(578,0),(301,3),(192,14),(0,17)] What's the best way to do this? Should I be using map!() somewhere? Thanks, AdamWith no promises on performance and with a bonus mind-blowing format string... :) I am sure it can be improved a lot. import std.stdio; import std.algorithm; import std.range; import std.conv; void main() { auto input = "192 14, 301 3, 578 0, 0 17"; auto result = input .splitter(',') .map!splitter .joiner .map!(to!int) .chunks(2) .map!array .array .sort() .retro; writeln(result); writefln("[%((%(%s,%))%|,%)]", result); } Prints both an array of arrays and the same format that you wanted: [[578, 0], [301, 3], [192, 14], [0, 17]] [(578,0),(301,3),(192,14),(0,17)] Ali
Jun 01 2015
auto result = input .splitter(',') .map!splitter .joiner .map!(to!int) .chunks(2) .map!array .array .sort() .retro;Thanks for the reply. I'm a bit confused by the splitter followed immediately by the joiner...and then it kinda falls apart for me. Here's where I've ended up: auto result = input .splitter(",") // range of strings .map!(v => v.splitter(" ") // range of ranges strings .array // range of arrays of strings .to!(int[])) // range of arrays of ints .Tuple!(int,int); Everything is fine until I try to instantiate Tuples with my arrays. Then I get an error that says none of the overloads of the constructor are callable with these arguments. But I see which makes me think it should work. Am I doing something wrong?
Jun 01 2015
Everything is fine until I try to instantiate Tuples with my arrays. Then I get an error that says none of the overloads of the constructor are callable with these arguments. But I see which makes me think it should work. Am I doing something wrong?Alright! I got what I wanted. Posting here for any fellow noobs who may stumble across this and care what I was screwing up. It looks like I accidentally gave a bad example, because I needed to sort on the second elements ascending, not the first elements descending. The lambdas I was feeding to sort were not working because of the crazy types coming from the range methods, and it turns out that I did not need tuples, since I could get a proper sort from an array. This is what I ended up with (plus a couple of filters that I'm omitting for clarity): auto result = input .splitter(",") .map!(v => v.splitter(" ") .map!(a => a.to!(int)) .array() ) .array() .sort!("a[1]<b[1]"); Thanks Ali and Dennis for taking time to respond.
Jun 01 2015
On Monday, 1 June 2015 at 22:31:38 UTC, Adam wrote:Hi, I have a string of pairs of integers, where pairs are delimited from each other by commas, and members of the pair are delimited by a space. I'd like to end up with something like a range of 2-tuplesI can offer this option: import std.stdio, std.algorithm, std.array, std.range, std.format, std.typecons; void main() { string s = "192 14, 301 3, 578 0, 0 17"; int[] arr; int tmp; foreach (el; s.split) { formattedRead(el, "%s", &tmp); arr ~= tmp; } Tuple!(int, int)[] tup; foreach (el; zip(arr.stride(2), arr.dropOne.stride(2))) { tup ~= tuple(el[0], el[1]); } tup.sort!"a[0] > b[0]"; writeln(tup); } /*[Tuple!(int, int)(578, 0), Tuple!(int, int)(301, 3), Tuple!(int, int)(192, 14), Tuple!(int, int)(0, 17)]*/
Jun 01 2015