Thread overview | ||||||
---|---|---|---|---|---|---|
|
May 19, 2019 How to get type returned by e.g. std.algorithm.iteration.filter | ||||
---|---|---|---|---|
| ||||
I would like to join several sorted files into one big sorted file. For that I came up with this snippet: #!/usr/bin/env rdmd import std.stdio; import std.algorithm; import std.typecons; import std.array; import std.range; auto byMinimum(Ranges)(Ranges ranges) { auto getNonEmpty() { return ranges.filter!("!a.empty"); } auto nonEmpty = getNonEmpty; struct ByMinimum(Ranges) { bool empty() { return nonEmpty.empty; } auto front() { auto minRangeAndLine = nonEmpty.map!(range => tuple!("range", "line")(range, range.front)).minElement!("a.line"); return minRangeAndLine; } void popFront() { auto minRangeAndLine = nonEmpty.map!(range => tuple!("range", "line")(range, range.front)).minElement!("a.line"); minRangeAndLine.range.popFront; nonEmpty = getNonEmpty; } } return ByMinimum!(Ranges)(); } void main(string[] files) { foreach (n; files[1 .. $].map!(name => File(name).byLine(No.keepTerminator)).array.byMinimum) { writeln(n.line); } } I would like to get rid of the duplication that searches for the range with the next minimum in terms of runtime but also in terms of code written out. Unfortunately I have no idea how to even store the result of this search in an attribute of ByMinimum, as I cannot writeout its type. Kind regards, Christian |
May 19, 2019 Re: How to get type returned by e.g. std.algorithm.iteration.filter | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christian Köstlin | On 2019-05-19 15:36, Christian Köstlin wrote: > Unfortunately I have no idea how to even store the result of this search in an attribute of ByMinimum, as I cannot writeout its type. In general you can use `typeof(<expression>)`, where `<expression>` is the expression you want to get the type of. -- /Jacob Carlborg |
May 19, 2019 Re: How to get type returned by e.g. std.algorithm.iteration.filter | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 19.05.19 20:38, Jacob Carlborg wrote: > On 2019-05-19 15:36, Christian Köstlin wrote: > >> Unfortunately I have no idea how to even store the result of this search in an attribute of ByMinimum, as I cannot writeout its type. > > In general you can use `typeof(<expression>)`, where `<expression>` is the expression you want to get the type of. > Thanks for the hint. The best I could come up with this is: #!/usr/bin/env rdmd import std.stdio; import std.algorithm; import std.typecons; import std.array; import std.range; import std.traits; auto byMinimum(Ranges)(Ranges ranges) { auto getNonEmpty() { return ranges.filter!("!a.empty"); } auto minimumOfRanges(Ranges)(Ranges ranges) { // dfmt off return ranges .map!(range => tuple!("range", "line")(range, range.front)) .minElement!("a.line"); // dfmt on } auto nonEmpty = getNonEmpty; ReturnType!(minimumOfRanges!(typeof(nonEmpty))) minRangeAndLine; struct ByMinimum(Ranges) { bool empty() { return nonEmpty.empty; } auto front() { minRangeAndLine = minimumOfRanges(nonEmpty); return minRangeAndLine; } void popFront() { minRangeAndLine.range.popFront; nonEmpty = getNonEmpty; } } return ByMinimum!(Ranges)(); } void main(string[] files) { foreach (n; files[1 .. $].map!(name => File(name).byLine(No.keepTerminator)).array.byMinimum) { writeln(n.line); } } Still it looks a little clumsy. Any ideas? -- Christian |
May 19, 2019 Re: How to get type returned by e.g. std.algorithm.iteration.filter | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christian Köstlin | Last version using more from the outer template #!/usr/bin/env rdmd import std.stdio; import std.algorithm; import std.typecons; import std.array; import std.range; import std.traits; auto byMinimum(Ranges)(Ranges ranges) { auto getNonEmpty() { return ranges.filter!("!a.empty"); } auto nonEmpty = getNonEmpty; auto minimumOfRanges() { // dfmt off return nonEmpty .map!(range => tuple!("range", "line")(range, range.front)) .minElement!("a.line"); // dfmt on } ReturnType!(minimumOfRanges) minRangeAndLine; struct ByMinimum { bool empty() { return nonEmpty.empty; } auto front() { minRangeAndLine = minimumOfRanges; return minRangeAndLine; } void popFront() { nonEmpty = getNonEmpty; minRangeAndLine.range.popFront; } } return ByMinimum(); } void main(string[] files) { foreach (n; files[1 .. $].map!(name => File(name).byLine(No.keepTerminator)).array.byMinimum) { writeln(n.line); } } |
Copyright © 1999-2021 by the D Language Foundation