Jump to page: 1 2
Thread overview
What's wrong with my usage of std.algorithm.map in this code example?
May 24, 2016
pineapple
May 25, 2016
pineapple
May 25, 2016
Chris
May 25, 2016
Chris
May 25, 2016
Chris
May 25, 2016
ag0aep6g
May 25, 2016
Chris
May 25, 2016
ag0aep6g
May 25, 2016
Chris
May 25, 2016
Era Scarecrow
May 26, 2016
Chris
May 25, 2016
FreeSlave
May 25, 2016
Chris
May 24, 2016
I would've expected this to work, but instead I get a compile error. Is my syntax wrong? Is this just not a case that map can handle, and I should be doing something else?

    import std.algorithm : map;
    import std.conv : to;
    import std.stdio : writeln;
    import std.string : join;

    string test(Args...)(in Args items){
        immutable string[items.length] itemstrings = map!(to!string)(items);
        return join(itemstrings, ", ");
    }

    unittest{
        writeln(test(1, 2, 3, 4));
    }

May 24, 2016
On 5/24/16 4:03 PM, pineapple wrote:
> I would've expected this to work, but instead I get a compile error. Is
> my syntax wrong? Is this just not a case that map can handle, and I
> should be doing something else?
>
>      import std.algorithm : map;
>      import std.conv : to;
>      import std.stdio : writeln;
>      import std.string : join;
>
>      string test(Args...)(in Args items){
>          immutable string[items.length] itemstrings =
> map!(to!string)(items);

Slice assignment from range to array is not supported.

In your example, I'm curious why the efforts to specify the type? I think it would work with just saying auto itemstrings = ...

-Steve
May 25, 2016
On Tuesday, 24 May 2016 at 20:18:34 UTC, Steven Schveighoffer wrote:
> Slice assignment from range to array is not supported.
>
> In your example, I'm curious why the efforts to specify the type? I think it would work with just saying auto itemstrings = ...
>
> -Steve

I still get an error if I use auto instead.
May 25, 2016
On Tuesday, 24 May 2016 at 20:03:14 UTC, pineapple wrote:
> I would've expected this to work, but instead I get a compile error. Is my syntax wrong? Is this just not a case that map can handle, and I should be doing something else?
>
>     import std.algorithm : map;
>     import std.conv : to;
>     import std.stdio : writeln;
>     import std.string : join;
>
>     string test(Args...)(in Args items){
>         immutable string[items.length] itemstrings = map!(to!string)(items);
>         return join(itemstrings, ", ");
>     }
>
>     unittest{
>         writeln(test(1, 2, 3, 4));
>     }

Works with 'only', 'array' and static array slicing.

import std.algorithm : map;
import std.range : only;
import std.conv : to;
import std.stdio : writeln;
import std.string : join;
import std.array : array;

string test(Args...)(in Args items){
    immutable string[items.length] itemstrings = map!(to!string)(only(items)).array;
    return join(itemstrings[], ", ");
}

unittest{
    writeln(test(1, 2, 3, 4));
}
May 25, 2016
On Wednesday, 25 May 2016 at 10:24:19 UTC, pineapple wrote:
> On Tuesday, 24 May 2016 at 20:18:34 UTC, Steven Schveighoffer wrote:
>> Slice assignment from range to array is not supported.
>>
>> In your example, I'm curious why the efforts to specify the type? I think it would work with just saying auto itemstrings = ...
>>
>> -Steve
>
> I still get an error if I use auto instead.

If you really need it, this works:

import std.algorithm : map;
import std.conv : to;
import std.stdio : writeln;
import std.string : join;

string test(Args...)(in Args items)
{
	writeln(items.stringof);
	string[] itemstrings;
	foreach (const ref i; items)
		itemstrings ~= i.to!string;
	// auto itemstrings = items.map!(a => a.to!string);
  return join(itemstrings, ", ");
}

unittest
{
  writeln(test(1, 2, "v", 4, 'c'));
}

If you use map!(), you get this error:

Error: template map_error.test!(int, int, string, int, char).test.map!((a) => a.to!string).map cannot deduce function from argument types !()(const(int), const(int), const(string), const(int), const(char)), candidates are:
/home/christoph/.dvm/compilers/dmd-2.071.0/linux/bin/../../src/phobos/std/algorithm/iteration.d(450):        map_error.test!(int, int, string, int, char).test.map!((a) => a.to!string).map(Range)(Range r) if (isInputRange!(Unqual!Range))

The argument types don't match, i.e. they are const(int) etc. instead of int. The arguments are passed as a tuple:

cf. writeln(items.stringof);
tuple(_param_0, _param_1, _param_2, _param_3, _param_4)


May 25, 2016
On Wednesday, 25 May 2016 at 11:14:26 UTC, FreeSlave wrote:
>
> Works with 'only', 'array' and static array slicing.
>
> import std.algorithm : map;
> import std.range : only;
> import std.conv : to;
> import std.stdio : writeln;
> import std.string : join;
> import std.array : array;
>
> string test(Args...)(in Args items){
>     immutable string[items.length] itemstrings = map!(to!string)(only(items)).array;
>     return join(itemstrings[], ", ");
> }
>
> unittest{
>     writeln(test(1, 2, 3, 4));
> }

Nice, but I think it doesn't work with varying types.

writeln(test(1, 2, "v", 4, 'c'));
May 25, 2016
On 5/25/16 6:24 AM, pineapple wrote:
> On Tuesday, 24 May 2016 at 20:18:34 UTC, Steven Schveighoffer wrote:
>> Slice assignment from range to array is not supported.
>>
>> In your example, I'm curious why the efforts to specify the type? I
>> think it would work with just saying auto itemstrings = ...
>>
>
> I still get an error if I use auto instead.

OK, I see the other issue now. map takes a range, whereas you are giving it a tuple.

-Steve
May 25, 2016
On Wednesday, 25 May 2016 at 12:08:20 UTC, Steven Schveighoffer wrote:
> On 5/25/16 6:24 AM, pineapple wrote:
>> On Tuesday, 24 May 2016 at 20:18:34 UTC, Steven Schveighoffer wrote:
>>> Slice assignment from range to array is not supported.
>>>
>>> In your example, I'm curious why the efforts to specify the type? I
>>> think it would work with just saying auto itemstrings = ...
>>>
>>
>> I still get an error if I use auto instead.
>
> OK, I see the other issue now. map takes a range, whereas you are giving it a tuple.
>
> -Steve

Why can the tuple be iterated with foreach, as in my quick fix, and indexed with tuple[0..], but is not accepted as a range? What are the differences? Is there a way to rangify a tuple?
May 25, 2016
On Wednesday, 25 May 2016 at 13:27:28 UTC, Chris wrote:
> On Wednesday, 25 May 2016 at 12:08:20 UTC, Steven Schveighoffer wrote:
>> On 5/25/16 6:24 AM, pineapple wrote:
>>> On Tuesday, 24 May 2016 at 20:18:34 UTC, Steven Schveighoffer wrote:
>>>> Slice assignment from range to array is not supported.
>>>>
>>>> In your example, I'm curious why the efforts to specify the type? I
>>>> think it would work with just saying auto itemstrings = ...
>>>>
>>>
>>> I still get an error if I use auto instead.
>>
>> OK, I see the other issue now. map takes a range, whereas you are giving it a tuple.
>>
>> -Steve
>
> Why can the tuple be iterated with foreach, as in my quick fix, and indexed with tuple[0..], but is not accepted as a range? What are the differences? Is there a way to rangify a tuple?

I should add : a homogeneous tuple, e.g. Tuple!(int, int, int);
May 25, 2016
On 05/25/2016 03:27 PM, Chris wrote:
> Why can the tuple be iterated with foreach, as in my quick fix, and
> indexed with tuple[0..], but is not accepted as a range? What are the
> differences?

popFront doesn't make sense with a tuple (aka expression list). When you remove the first element of a tuple, you get another tuple of a different type, but popFront can't change the type of the range.

In code:

----
void main()
{
    import std.meta: AliasSeq;
    AliasSeq!(int, int, int) tuple = AliasSeq!(1, 2, 3);
    tuple.popFront(); /* How would this be implemented? Would have to change tuple's type to AliasSeq!(int, int). */
}
----

> Is there a way to rangify a tuple?

std.range.only:

----
void main()
{
    import std.meta: AliasSeq;
    import std.range: only;
    AliasSeq!(int, int, int) tuple = AliasSeq!(1, 2, 3);
    auto range = only(tuple);
    range.popFront(); /* ok */
}
----
« First   ‹ Prev
1 2