www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - D slicing

reply "Colin Grogan" <grogan.colin gmail.com> writes:
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?
Jun 17 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Jun 17 2013
prev sibling next sibling parent "Andrej Mitrovic" <andrej.mitrovich gmail.com> writes:
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.
Jun 17 2013
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Jun 17 2013
parent "Colin Grogan" <grogan.colin gmail.com> writes:
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! ;)
Jun 18 2013