Thread overview
A slice consisting of non-consecutive elements of an array?
Jan 12, 2022
forkit
Jan 12, 2022
vit
Jan 12, 2022
forkit
Jan 12, 2022
vit
Jan 12, 2022
vit
Jan 13, 2022
forkit
Jan 13, 2022
Stanislav Blinov
Jan 13, 2022
forkit
January 12, 2022
I am familiar with the concept of a slice in D.

However, a slice is a consecutive slice, is in not? (e.g) [4..$-1]

I would like a slice (or a view, or whatever name you wanna call it), of particular elements within an array that may not be consecutive. e.g. [4-7,8,10,13-16]

Consider below:

I want a slice/view on this array that only contains elements with the string "one".

["one", "one", "two", "one", "two", "one", "one", "two]

Most importantly, I do NOT want to allocate - so the slice/view needs to be 'referencing'  existing data (not copying it).

Yes, I can hard code it, C style. I already know this.

Does phobos offer something like this?


January 12, 2022

On Wednesday, 12 January 2022 at 05:27:08 UTC, forkit wrote:

>

I am familiar with the concept of a slice in D.

However, a slice is a consecutive slice, is in not? (e.g) [4..$-1]

I would like a slice (or a view, or whatever name you wanna call it), of particular elements within an array that may not be consecutive. e.g. [4-7,8,10,13-16]

Consider below:

I want a slice/view on this array that only contains elements with the string "one".

["one", "one", "two", "one", "two", "one", "one", "two]

Most importantly, I do NOT want to allocate - so the slice/view needs to be 'referencing' existing data (not copying it).

Yes, I can hard code it, C style. I already know this.

Does phobos offer something like this?

Yes std.algorithm : filter.

import std.stdio : writeln;
import std.algorithm : filter;

    void main()@safe{
        auto a = ["one", "one", "two", "one", "two", "one", "one", "two"];

    	writeln(a);
    	writeln(a.filter!(x => x == "one"));
    }
    ```
January 12, 2022

On Wednesday, 12 January 2022 at 06:16:49 UTC, vit wrote:

>

Yes std.algorithm : filter.

import std.stdio : writeln;
import std.algorithm : filter;

    void main()@safe{
        auto a = ["one", "one", "two", "one", "two", "one", "one", "two"];

    	writeln(a);
    	writeln(a.filter!(x => x == "one"));
    }
    ```

Interesting. I looked it up.. it says "returns a new range..."

Does that mean what I think it means (i.e. a new allocation takes place) ?

January 12, 2022

On Wednesday, 12 January 2022 at 06:43:40 UTC, forkit wrote:

>

On Wednesday, 12 January 2022 at 06:16:49 UTC, vit wrote:

>

Yes std.algorithm : filter.

import std.stdio : writeln;
import std.algorithm : filter;

    void main()@safe{
        auto a = ["one", "one", "two", "one", "two", "one", "one", "two"];

    	writeln(a);
    	writeln(a.filter!(x => x == "one"));
    }
    ```

Interesting. I looked it up.. it says "returns a new range..."

Does that mean what I think it means (i.e. a new allocation takes place) ?

No, it is only view to old slice:

void main()@safe{
    auto a = ["one", "one", "two", "one", "two", "one", "one", "two"];

    auto b = (()@nogc => a.filter!(x => x == "one"))();
    writeln(a);
    writeln(b);
}
January 12, 2022

On Wednesday, 12 January 2022 at 06:58:47 UTC, vit wrote:

>

On Wednesday, 12 January 2022 at 06:43:40 UTC, forkit wrote:

>

On Wednesday, 12 January 2022 at 06:16:49 UTC, vit wrote:

>

Yes std.algorithm : filter.

import std.stdio : writeln;
import std.algorithm : filter;

    void main()@safe{
        auto a = ["one", "one", "two", "one", "two", "one", "one", "two"];

    	writeln(a);
    	writeln(a.filter!(x => x == "one"));
    }
    ```

Interesting. I looked it up.. it says "returns a new range..."

Does that mean what I think it means (i.e. a new allocation takes place) ?

No, it is only view to old slice:

void main()@safe{
    auto a = ["one", "one", "two", "one", "two", "one", "one", "two"];

    auto b = (()@nogc => a.filter!(x => x == "one"))();
    writeln(a);
    writeln(b);
}

filter is implemented like this (but more generic):

import std.stdio : writeln;


auto filter(alias fn, T)(T[] slice){

    //InputRange:
    static struct Filter{
    	T[] slice;
        bool empty()const{return slice.length == 0;}
        T front(){return slice[0];}
        void popFront(){
            do{
            	slice = slice[1 .. $];
            }while(slice.length && !fn(slice[0]));
        }
    }

    return Filter(slice);
}

void main()@safe{
    auto a = ["one", "one", "two", "one", "two", "one", "one", "two"];

    writeln(a);
    writeln(a.filter!(x => x == "one"));
}
January 13, 2022
On Wednesday, 12 January 2022 at 06:16:49 UTC, vit wrote:
>
> Yes std.algorithm : filter.
>
> ```d
> import std.stdio : writeln;
> import std.algorithm : filter;
>
>     void main()@safe{
>         auto a = ["one", "one", "two", "one", "two", "one", "one", "two"];
>
>     	writeln(a);
>     	writeln(a.filter!(x => x == "one"));
>     }
>     ```

Any idea on how I can get a ptr (without hardcoding C style)

e.g. something like this:

immutable(string)*[] pointers = strings.filter!(x => x == "one").to!pointers.array;

January 13, 2022
On Thursday, 13 January 2022 at 19:52:27 UTC, forkit wrote:

> Any idea on how I can get a ptr (without hardcoding C style)
>
> e.g. something like this:
>
> immutable(string)*[] pointers = strings.filter!(x => x == "one").to!pointers.array;

```d
import std.stdio : writeln;
import std.algorithm : filter, map, each;
import std.range : array;

void main() @safe
{
    immutable strings = ["one", "one", "two", "one", "two", "one", "one", "two"];
    immutable(string)*[] pointers = strings.filter!(x => x == "one").map!((ref x) @trusted => &x).array;
    pointers.each!(p => writeln(p - &strings[0]));
}
```
January 13, 2022
On Thursday, 13 January 2022 at 20:32:40 UTC, Stanislav Blinov wrote:
> On Thursday, 13 January 2022 at 19:52:27 UTC, forkit wrote:
>
>> Any idea on how I can get a ptr (without hardcoding C style)
>>
>> e.g. something like this:
>>
>> immutable(string)*[] pointers = strings.filter!(x => x == "one").to!pointers.array;
>
> ```d
> import std.stdio : writeln;
> import std.algorithm : filter, map, each;
> import std.range : array;
>
> void main() @safe
> {
>     immutable strings = ["one", "one", "two", "one", "two", "one", "one", "two"];
>     immutable(string)*[] pointers = strings.filter!(x => x == "one").map!((ref x) @trusted => &x).array;
>     pointers.each!(p => writeln(p - &strings[0]));
> }
> ```

just perfect! thanks.