We have slices, do we have Strides?

Kai Meyer kai at unixlords.com
Tue Aug 9 09:30:49 PDT 2011


On 08/09/2011 09:37 AM, Steven Schveighoffer wrote:
> On Tue, 09 Aug 2011 11:29:52 -0400, Kai Meyer <kai at unixlords.com> wrote:
>
>> On 08/08/2011 05:25 PM, Steven Schveighoffer wrote:
>>> On Mon, 08 Aug 2011 18:33:55 -0400, Kai Meyer <kai at unixlords.com> wrote:
>>>
>>>> On 08/08/2011 12:55 PM, Jonathan M Davis wrote:
>>>>>> I have a problem I'd really like to use Strides for to simplify my
>>>>>> code.
>>>>>> Currently, I do this:
>>>>>> foreach(n; 0..chunks)
>>>>>> comp_arr[n] = values[(n * step_size) + n]
>>>>>> if(!all_same(comp_arr, comp_arr[0]))
>>>>>>
>>>>>> It would eliminate an entire 2 lines of code for each time I want
>>>>>> strides, to be able to do this:
>>>>>> if(!all_same(bytes[i..$..step_size])
>>>>>>
>>>>>> Meaning, start with i, grab all elements at i + block_size * n until
>>>>>> block_size * n> bytes.length. Right?
>>>>>>
>>>>>> -Kai Meyer
>>>>>
>>>>> Would std.range.stride work for you?
>>>>>
>>>>> - Jonathan M Davis
>>>>
>>>> It would, if there was a way to give it an offset:
>>>>
>>>> int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
>>>
>>> fixed:
>>>
>>>> assert(equal(stride(a, 3), [ 1, 4, 7, 10 ][]));
>>>> assert(equal(stride(a[1..$], 3), [ 2, 5, 8, 11 ][]));
>>>> assert(equal(stride(a[2..$], 3), [ 3, 6, 9 ][]));
>>>> assert(equal(stride(a[3..$], 3), [ 4, 7, 10 ][]));
>>>
>>> -Steve
>>
>> Doh, how do I extract the array from the return value of stride?
>>
>> import std.range;
>> int do_something(int[] values)
>> {
>> return values[0];
>> }
>> void main(string[] args)
>> {
>> int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
>> do_something(stride(a,3));
>> }
>>
>>
>> I get:
>> moo.d(9): Error: function moo.do_something (int[] values) is not
>> callable using argument types (Result)
>> moo.d(9): Error: cannot implicitly convert expression (stride(a,3LU))
>> of type Result to int[]
>
> Two options, first, you can change do_something to accept a range
> (depending on what the real implementation of do_something is, you might
> need to require a random-access range, but that dummy implementation
> could accept any input range, just return x.front):
>
> int do_something(R)(R values) if (isInputRange!R && is(ElementType!R :
> int))
> {
> return values.front; // maybe need random access in real code?
> }
>
> Second option, convert range to an array. This incurs a memory
> allocation to create the array:
>
> import std.array;
>
> ...
> void main(...)
> {
> ...
> do_something(array(stride(a, 3)));
> }
>
> doc for std.array.array:
> http://www.d-programming-language.org/phobos/std_array.html#array
>
> -Steve

Both of those solutions worked, thanks :)


More information about the Digitalmars-d-learn mailing list