Re: Unpacking Slices

2021-06-14 Thread jfondren via Digitalmars-d-learn

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;
assert(names.length == vals.length, "wrong # params to 
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);
}
```


Re: Unpacking Slices

2021-06-14 Thread Vladimir Panteleev via Digitalmars-d-learn

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;
```



Re: Unpacking Slices

2021-06-14 Thread Ali Çehreli via Digitalmars-d-learn

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