www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A slice consisting of non-consecutive elements of an array?

reply forkit <forkit gmail.com> writes:
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?
Jan 11 2022
parent reply vit <vit vit.vit> writes:
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. ```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")); } ```
Jan 11 2022
next sibling parent reply forkit <forkit gmail.com> writes:
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"));
     }
     ```
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) ?
Jan 11 2022
parent reply vit <vit vit.vit> writes:
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.

 ```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"));
     }
     ```
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: ```d 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); } ```
Jan 11 2022
parent vit <vit vit.vit> writes:
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.

 ```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"));
     }
     ```
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: ```d 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): ```d 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")); } ```
Jan 11 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
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;
Jan 13 2022
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
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])); } ```
Jan 13 2022
parent forkit <forkit gmail.com> writes:
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.
Jan 13 2022