www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Unpacking Slices

reply Justin Choi <justinjchoice gmail.com> writes:
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
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
prev sibling next sibling parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
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
prev sibling parent jfondren <julian.fondren gmail.com> writes:
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