Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
June 17, 2013 D slicing | ||||
---|---|---|---|---|
| ||||
Hi all. Wondering what way I'd go about this, I want to slice an array into two arrays. First array containing every even index (i.e. 0,2,4,6,8..$) Second slice containing every odd index (i.e. 1,3,5,7,9..$) <-- be some issue with using $ depending on if orig length is odd or even. Can work that out easily enough... Reading the articles on array slicing its not clear if its possible. Ideally, I could do something like the following: auto orig = [1,2,3,4,5,6,7]; auto sliceEven = orig[0..$..2]; auto sliceOdd = orig[1..$..2]; But I dont think thats possible? Any idears? |
June 17, 2013 Re: D slicing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | Colin Grogan:
> Reading the articles on array slicing its not clear if its possible.
I presume Walter thinks that slicing with a stride is a not common enough operation to put it into D. His choices on such things are a bit arbitrary.
One way to do it:
import std.stdio, std.array, std.range;
void main() {
auto orig = [1, 2, 3, 4, 5, 6, 7];
auto sliceOdd = orig.stride(2).array;
sliceOdd.writeln;
auto sliceEven = orig[1..$].stride(2).array;
sliceEven.writeln;
}
stride() is just a function used with UFCS.
Don't use ".array" if you just need a lazy sequence.
Bye,
bearophile
|
June 17, 2013 Re: D slicing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | On Monday, 17 June 2013 at 23:34:46 UTC, Colin Grogan wrote: > auto orig = [1,2,3,4,5,6,7]; > auto sliceEven = orig[0..$..2]; > auto sliceOdd = orig[1..$..2]; > > But I dont think thats possible? Not with arrays, they must be contiguous. But you can use ranges instead: ----- import std.stdio; import std.range; void main() { auto orig = [1,2,3,4,5,6,7]; auto sliceEven = orig.stride(2); auto sliceOdd = orig.drop(1).stride(2); writeln(sliceEven); writeln(sliceOdd); } ----- You can convert the ranges into arrays by calling .array on them (and importing std.array first), but this will cause allocations. |
June 17, 2013 Re: D slicing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Colin Grogan | On 06/17/2013 04:34 PM, Colin Grogan wrote: > Wondering what way I'd go about this, I want to slice an array into two > arrays. First array containing every even index (i.e. 0,2,4,6,8..$) > Second slice containing every odd index (i.e. 1,3,5,7,9..$) <-- be some > issue with using $ depending on if orig length is odd or even. Can work > that out easily enough... > > Reading the articles on array slicing its not clear if its possible. > > Ideally, I could do something like the following: > > auto orig = [1,2,3,4,5,6,7]; > auto sliceEven = orig[0..$..2]; > auto sliceOdd = orig[1..$..2]; If you want the data sit where it is but simply have different views in it, then you must use ranges. There are multiple ways. Here is one using std.range.stride: import std.stdio; import std.range; void main() { auto orig = [0, 1, 2, 3, 4, 5, 6, 7]; auto sliceEven = orig.stride(2); auto sliceOdd = orig.dropOne.stride(2); writeln(sliceEven); writeln(sliceOdd); } The output: [0, 2, 4, 6] [1, 3, 5, 7] Or you can generate the indexes and then get a view that way: auto sliceEven = orig.indexed(iota(0, orig.length, 2)); auto sliceOdd = orig.indexed(iota(1, orig.length, 2)); Ali |
June 18, 2013 Re: D slicing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Monday, 17 June 2013 at 23:48:36 UTC, Ali Çehreli wrote:
> On 06/17/2013 04:34 PM, Colin Grogan wrote:
>
> > Wondering what way I'd go about this, I want to slice an
> array into two
> > arrays. First array containing every even index (i.e.
> 0,2,4,6,8..$)
> > Second slice containing every odd index (i.e. 1,3,5,7,9..$)
> <-- be some
> > issue with using $ depending on if orig length is odd or
> even. Can work
> > that out easily enough...
> >
> > Reading the articles on array slicing its not clear if its
> possible.
> >
> > Ideally, I could do something like the following:
> >
> > auto orig = [1,2,3,4,5,6,7];
> > auto sliceEven = orig[0..$..2];
> > auto sliceOdd = orig[1..$..2];
>
> If you want the data sit where it is but simply have different views in it, then you must use ranges. There are multiple ways.
>
> Here is one using std.range.stride:
>
> import std.stdio;
> import std.range;
>
> void main()
> {
> auto orig = [0, 1, 2, 3, 4, 5, 6, 7];
>
> auto sliceEven = orig.stride(2);
> auto sliceOdd = orig.dropOne.stride(2);
>
> writeln(sliceEven);
> writeln(sliceOdd);
> }
>
> The output:
>
> [0, 2, 4, 6]
> [1, 3, 5, 7]
>
> Or you can generate the indexes and then get a view that way:
>
> auto sliceEven = orig.indexed(iota(0, orig.length, 2));
> auto sliceOdd = orig.indexed(iota(1, orig.length, 2));
>
> Ali
Thats perfect folks. Should have known to look in std.range.
This works for me perfectly.
3 answers all within a couple minutes of each other, what a good community! ;)
|
Copyright © 1999-2021 by the D Language Foundation