digitalmars.D.learn - Unpacking Slices
- Justin Choi (4/4) Jun 14 2021 Is there any shortcut for unpacking slices like I'd want to do in
- =?UTF-8?Q?Ali_=c3=87ehreli?= (49/53) Jun 14 2021 D does not have automatic unpacking. Here is a quick, dirty, and fun
- Vladimir Panteleev (9/13) Jun 14 2021 I tried to implement PHP's "list" language construct here, which
- jfondren (26/30) Jun 14 2021 This doesn't leave you with multiple local variables, but it
Is there any shortcut for unpacking slices like I'd want to do in a scenario like this? `info = readln.strip.split;` `string a = info[0], b = info[1], c = info[2];`
Jun 14 2021
On 6/14/21 11:08 AM, Justin Choi wrote:Is there any shortcut for unpacking slices like I'd want to do in a scenario like this? `info = readln.strip.split;` `string a = info[0], b = info[1], c = info[2];`D does not have automatic unpacking. Here is a quick, dirty, and fun experiment: struct Unpack(Args...) { static string typeName(size_t n)() { return Args[n].stringof; } static char varName(size_t n) { return cast(char)('a' + n); } // Variable declarations static foreach (n; 0 .. Args.length) { mixin (typeName!n ~ ' ' ~ varName(n) ~ ';'); } // Get by variable number auto get(size_t n)() { mixin ("return " ~ varName(n) ~ ';'); } // Set by variable number auto set(size_t n, T)(T value) { mixin (varName(n) ~ " = value;"); } } template unpack(Args...) { auto unpack(R)(R range) { auto result = Unpack!(Args)(); static foreach (n; 0 .. Args.length) { import std.range : front, popFront; result.set!n(range.front); range.popFront(); } return result; } } import std.stdio; import std.string; void main() { auto info = readln.strip.split; auto u = info.unpack!(string, string, string); // Variables are accessed by name as a, b, etc. or by number: assert(u.a == u.get!0); assert(u.b == u.get!1); assert(u.c == u.get!2); } When all variable types are the same, the usage can be improved to allow e.g. info.unpack!(3, string) That's not implemented yet. :) Ali
Jun 14 2021
On Monday, 14 June 2021 at 18:08:27 UTC, Justin Choi wrote:Is there any shortcut for unpacking slices like I'd want to do in a scenario like this? `info = readln.strip.split;` `string a = info[0], b = info[1], c = info[2];`I tried to implement PHP's "list" language construct here, which does something similar: https://github.com/cybershadow/ae/blob/next/utils/array.d#L763 For your example, it would look like: ```d string a, b, c; list(a, b, c) = readln.strip.split; ```
Jun 14 2021
On Monday, 14 June 2021 at 18:08:27 UTC, Justin Choi wrote:Is there any shortcut for unpacking slices like I'd want to do in a scenario like this? `info = readln.strip.split;` `string a = info[0], b = info[1], c = info[2];`This doesn't leave you with multiple local variables, but it leaves you with names instead of numbers for the members of the slice: ```d import std.stdio, std.typecons, std.algorithm, std.array, std.conv, std.range; auto tuple(string rawnames, T)(T[] vals) { const names = rawnames.splitter(' ').array; tuple()"); mixin("auto ret = Tuple!(" ~ names.map!(n => T.stringof ~ `, "` ~ n ~ `"`).joiner(", ").array ~ ")(" ~ names.length.iota.map!(i => "vals[" ~ i.to!string ~ "]").joiner(", ").array ~ ");"); return ret; } void main() { int[] x = [1,2,3]; auto tup = tuple!"a b c"(x); writeln(tup.b); } ```
Jun 14 2021