Jump to page: 1 2
Thread overview
Assigning to array of structs with custom constructor
Apr 25, 2022
cc
Apr 25, 2022
Alain De Vos
Apr 25, 2022
cc
Apr 25, 2022
Stanislav Blinov
Apr 25, 2022
cc
Apr 25, 2022
Ali Çehreli
Apr 25, 2022
cc
Apr 25, 2022
rassoc
Apr 25, 2022
Salih Dincer
Apr 26, 2022
Ali Çehreli
Apr 26, 2022
Salih Dincer
Apr 26, 2022
Ali Çehreli
Apr 26, 2022
Salih Dincer
Apr 26, 2022
Ali Çehreli
April 25, 2022
struct Foo {
	string s;
	this(string s) { this.s = s; }
}
Foo foo = "a";
Foo[] foos = ["a"]; // Error: cannot implicitly convert expression `["a"]` of type `string[]` to `Foo[]`
Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast `"a"` of type `string` to type `Foo`

Was there a way to do this? I thought I recalled seeing something like this before, but I can't seem to find it.

April 25, 2022

Not really an answer but this works,

struct Foo {
	string s;
	this(string s) { this.s = s; }
}

void main(){
Foo foo = "a";
Foo[] foos;
foos ~=foo;
}%
April 25, 2022

On Monday, 25 April 2022 at 15:00:13 UTC, Alain De Vos wrote:

>

Not really an answer but this works,

void main(){
Foo foo = "a";
Foo[] foos;
foos ~=foo;
}%

Right, I can append individual elements, but can't assign or append a slice of a type that can be individually cast to the struct.

April 25, 2022

On Monday, 25 April 2022 at 14:36:25 UTC, cc wrote:

>
struct Foo {
	string s;
	this(string s) { this.s = s; }
}
Foo foo = "a";
Foo[] foos = ["a"]; // Error: cannot implicitly convert expression `["a"]` of type `string[]` to `Foo[]`
Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast `"a"` of type `string` to type `Foo`

Was there a way to do this? I thought I recalled seeing something like this before, but I can't seem to find it.

Make it explicit:

Foo[] foos = [Foo("a")];
April 25, 2022

On Monday, 25 April 2022 at 15:13:51 UTC, Stanislav Blinov wrote:

>

Make it explicit:

Foo[] foos = [Foo("a")];

There's that too, but I still have to iterate manually. e.g.:

string[] ss = loadABunchOfStringsFromSomewhere();
//Foo[] foos = ss; //error
Foo[] foos;
foos.reserve(ss.length);
foreach (s; ss)
	foos ~= Foo(s);

Was just hoping there was a way to streamline it within the struct definition.

April 25, 2022
On 4/25/22 07:36, cc wrote:
> ```d
> struct Foo {
>      string s;
>      this(string s) { this.s = s; }
> }
> Foo foo = "a";

I don't understand why that syntax exists. I always write it like this:

  auto foo = Foo("a");

> Foo[] foos = ["a"]; // Error: cannot implicitly convert expression
> `["a"]` of type `string[]` to `Foo[]`

This is a way:

  Foo[] foos = [Foo("a")];

Or:

  import std.stdio;
  import std.algorithm;
  import std.range;
  import std.conv;
  auto arr = iota(10).map!(i => Foo(i.text)).array;
  writeln(arr);

Ali

April 25, 2022
On 4/25/22 16:36, cc via Digitalmars-d-learn wrote:
> ```d
> struct Foo {
>      string s;
>      this(string s) { this.s = s; }
> }
> Foo foo = "a";
> Foo[] foos = ["a"]; // Error: cannot implicitly convert expression `["a"]` of type `string[]` to `Foo[]`
> Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast `"a"` of type `string` to type `Foo`
> ```
> 
> Was there a way to do this?  I thought I recalled seeing something like this before, but I can't seem to find it.

This works:

```d
import std;

void main() {
    struct Foo { string s; }
    Foo[] arr = ["abc", "def", "ghi"].map!Foo.array;
    arr.writeln; // => [Foo("abc"), Foo("def"), Foo("ghi")]
}
```
April 25, 2022
On Monday, 25 April 2022 at 15:23:12 UTC, Ali Çehreli wrote:
>   auto arr = iota(10).map!(i => Foo(i.text)).array;

On Monday, 25 April 2022 at 16:11:47 UTC, rassoc wrote:
>     Foo[] arr = ["abc", "def", "ghi"].map!Foo.array;

Ahh that'll do it alright, thanks
April 25, 2022

On Monday, 25 April 2022 at 16:11:47 UTC, rassoc wrote:

>
import std;

void main() {
    struct Foo { string s; }
    Foo[] arr = ["abc", "def", "ghi"].map!Foo.array;
    arr.writeln; // => [Foo("abc"), Foo("def"), Foo("ghi")]
}

Thank you...

Very very nice and simple but not extensible!

Because it cannot be used with other possibilities such as chunks() and take(). Also it cannot be customized with toString(). I guess even when this() constructor is added, map() explodes! So it not to explode, it is necessary to move away from simplicity:

import std.algorithm;
import std.range, std.stdio;

void main() {
  struct Foo {
    string s; /*
    string s;
    string toString() {
      return s;
    }//*/
  }
  auto arr1 = ["abc", "def", "ghi"]
              .map!Foo.array; /*
              .map!(a => Foo(a))
              .array;//*/

  typeof(arr1).stringof.writeln(": ", arr1);

  struct Bar {
    string s;
    //*
    this(R)(R result) {
      import std.conv : to;
      this.s = result.to!string;
    }//*/

    string toString() {
      return s;
    }
  }
  auto arr2 = "abcdefghi"
             .chunks(3)
             .map!(a => Bar(a))
             .array;

  typeof(arr2).stringof.writeln(": ", arr2);

} /* OUTPUT:
Foo[]: [Foo("abc"), Foo("def"), Foo("ghi")]
Bar[]: [abc, def, ghi]
*/

SDB@79

April 25, 2022
On 4/25/22 16:59, Salih Dincer wrote:

> Because it cannot be used with other possibilities such as
> ```chunks()``` and ```take()```.

There must be something wrong. map is commonly used with chunks(), take(), etc.

> Also it cannot be customized with
> ```toString()```.

Can you show examples of these please?

> I guess even when ```this()``` constructor is added,
> ```map()``` explodes!

Ah! Now I tried *removing* Bar.this and the compilation failed. Perhaps you left the working code in? (?)

For others:

1) Remove Bar.this

2) The code will fail below:

  auto arr2 = "abcdefghi"
             .chunks(3)
             .map!(a => Bar(a))   <-- ERROR
             .array;

Error: cannot implicitly convert expression `a` of type `Take!string` to `string`

One confusing thing is the fact that we learn that chunks uses take in its implementation. I think it's cool but a newcomer may be confused with where that Take comes from. Let's put that aside.

Then the compilation error is easy to understdand because chunks returns a range itself but it is not possible to make a Bar from a range. I don't agree that this is a problem with map's usability. The type system doesn't know what to do.

Here is one way of fixing the issue, not surprisingly, with map itself. ;)

  import std.conv : to;
  auto arr2 = "abcdefghi"
             .chunks(3)
             .map!(c => c.to!string) // <-- ADDED
             .map!(a => Bar(a))
             .array;

Or, one can use a single map expression:

  auto arr2 = "abcdefghi"
             .chunks(3)
             .map!(a => Bar(a.to!string))  // <-- COMBINED
             .array;

Or, a function can be called, etc.

But to remove a misunderstanding, map can be used with most other range algorithms, in the standard library, provided by the programmer, etc.

Ali

« First   ‹ Prev
1 2