Thread overview
A slice consisting of non-consecutive elements of an array?
Jan 12
forkit
Jan 12
vit
Jan 12
forkit
Jan 12
vit
Jan 12
vit
Jan 13
forkit
Jan 13
forkit
January 12
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

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

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

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

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
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
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
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.