November 10, 2006 Re: Array Slice Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | > Wouldn't that be -1? But the point stands. Ah, yes of course. > Also how do you get a 0 length slice with inclusive? > exclusive > data[0..0].length == 0; > inclusive > data[0..0].length == 1; Hmm, why it's so important ? |
November 10, 2006 Re: Array Slice Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | arr[1 ..= 5] is cool for inclusive.. but... arr[1 -> 5] is simple and the -> isn't being used in D anyways.. It could be the inclusive range.. TROUGH.... Eh? '->' for president!! |
November 10, 2006 Re: Array Slice Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to %u | == Quote from %u (trevorparscal@hotmail.com)'s article > I'm learning ruby right now, and I noticed they use a very cool syntax for ranges. > 0..5 means 0, 1, 2, 3, 4, 5 > 0...5 means 0, 1, 2, 3, 4 > The current array slicing is useful half the time and a pain in the arse the > other half, so I was wondering if anyone else has mentioned this idea for D > before... > - Trevor Well, the difference is that in D 0..5 doesn't mean 0,1,2,3,4,5, but 'starting from 0, 5 positions'. thus, if you want 0,1,2,3,4 you use, well, 0..4. I know what you mean, though, if you have 1..x you need sometimes to use 1..x-1, but hey, it doesn't look that bad, and having two different yet very simillar notations for 'inclusive' and 'exclusive' sounds like a great srouce of bugs. Cheers, Mariano. Mariano. |
November 10, 2006 Re: Array Slice Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nikita Kalaganov | Nikita Kalaganov wrote:
>>Wouldn't that be -1? But the point stands.
>
>
> Ah, yes of course.
>
>
>>Also how do you get a 0 length slice with inclusive?
>>exclusive
>>data[0..0].length == 0;
>>inclusive
>>data[0..0].length == 1;
>
>
> Hmm, why it's so important ?
int[] a, b, c;
a = ...
b = ...
// insert before i
int i = ...;
// exclusive slices
c = a[0..i] ~ b ~ a[i..$];
//vs.
// inclusive slices
if(i==0)
c = b ~ a;
else if(i == a.length)
c = a ~ b;
else
c = a[0..i-1] ~ b ~ a[i..$];
having the identity a == a[0..i]~a[i..$] is nice.
|
November 10, 2006 Re: Array Slice Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
> %u wrote:
>
>> I'm learning ruby right now, and I noticed they use a very cool syntax for ranges.
>>
>> 0..5 means 0, 1, 2, 3, 4, 5
>> 0...5 means 0, 1, 2, 3, 4
>>
>> The current array slicing is useful half the time and a pain in the arse the
>> other half, so I was wondering if anyone else has mentioned this idea for D
>> before...
>
>
> I have a bit of a problem with .. vs ..., I think they both look too similar making it hard to review code for correctness, and I'd have a hard time remembering which means which, another source of bugs.
When I tried to solve the problem, the best I could come up with was
[0..5] 0,1,2,3,4,5
[0..5<] 0,1,2,3,4
[>0..5] 1,2,3,4,5
[>0..5<] 1,2,3,4
I feel that [> and <] are reasonnably intuitive operators.
But it change D's default so I suppose that this isn't possible as this means that D[0..length] would have to be replaced by D[0..length<] or introducing a new keyword D[0..last] 'last' being length-1 of course, the index of the last element of the array.
Regards,
RenoX
|
November 10, 2006 Re: Array Slice Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fredrik Olsson Attachments: | Fredrik Olsson wrote: > I also like to yet again say that having ranges as a type that can easily be based around would be neat. > > bool checkAge(int age, int min, int max) { ... } > auto ok = checkAge(bar, 18, 25); > or > bool checkAge(int age, int$ range) { ... } > auto ok = checkAge(bar, 18...25); > > Well how to denote a range type, is something I have not figured out yet. So I went for a $ suffix in the example. > > > As an extension, sets is just as useful! > > int<> myFriendsAges = <18, 25, 21>; > bool foo = allAgesInRangeOver21(myFriendsAges); > > > And imagine slicing an array with a set! > Person[] primePersons = allPersons[<2,3,5,7,11>]; Hmm this got me thinking, why not just use an array? I beleive I wrote earlier that opIndex didn't work with non-int types. Apparently I was wrong. Sorry for spreading FUD. I think maybe what didn't work was non-int with opSlice, but that's ok, since you can easily make opIndex act like a slicer. So how does this look? For a Class c containing the array: float a[] = [10,11,12,13,14,15,16,17,18,19,20]; c[3] = 13 c[[1,4,2,0,7]] = [11,14,12,10,17] c[Range(2)] = [12,13,14,15,16,17,18,19,20] c[Range(2,4)] = [12,13] c[Range(2,8,2)] = [12,14,16] c[Range(2,null,2)] = [12,14,16,18,20] c[Range(8,2,-2)] = [18,16,14] For the plain array we can't overload opIndex, so we have to call a method: float a[] = [10,11,12,13,14,15,16,17,18,19,20]; a.slice([1,4,2,0,7]) = [11,14,12,10,17] a.slice(Range(2)) = [12,13,14,15,16,17,18,19,20] a.slice(Range(2,4)) = [12,13] a.slice(Range(2,8,2)) = [12,14,16] a.slice(Range(2,null,2)) = [12,14,16,18,20] a.slice(Range(2,8,-2)) = [18,16,14] You can even index with an array of Ranges! (If you really want to...) c([Range(4,-1,-2), Range(5,10,2)]) = [14,13,12,11,10,15,16,17,18,19] Also helpful methods .list and opApply: Range(0,5).list = [0,1,2,3,4] Range(4,null,-1).list = [4,3,2,1,0] Range(0,10,2).list = [0,2,4,6,8] Range(8,-1,-2).list = [8,6,4,2,0] foreach(i,Range(0,10,2)): 0, 2, 4, 6, 8, foreach(i,Range(8,-1,-2)): 8, 6, 4, 2, 0, foreach(i,Range(0,null,3)): 0, 3, 6, 9, 12, ...<break> What's not so hot, could be improved: D Limitations: * Can't overload opIndex for built-in arrays :-( * Can't make the 'slice' function return a plain T for slice(int), rather than a T[]. That is, I can't figure out how to do it without breaking IFTI, and I think we can agree arr.slice!(float[],int[])([4,5,6]) pretty much kills the convenience factor. * slice can't be extended with new native index types. In C++ it would be possible to add custom specializations of the slice template, so I could define my own slice(T[],SetIndex) that would get looked up. In D that gives you an IFTI error (can't specialize automatically deduced type). The result is that in D it has to all go inside the one mondo slice template as static if cases. 3rd parties can't extend the behavior. Limitations of my implementation: * I focused on positive ranges, to allow indexing everthing that can be reached by a size_t, but a version using signed values might be useful too. * A version that does inclusive ranging might be nice as well, but I couldn't think of a good way to do that without just duplicating most of the code. Ooh, maybe you could abuse complex literals for that! Range(2, 5i) --> means 2 to 5 inclusive. Ooh that works, it's in the attached file too. * You could imagine adding to the slice template to support anything with an opApply that generates ints. Or a Set type, or anything for that matter. (But it all has to be added inside that one 'slice' template as far as I can tell.) --bb |
November 12, 2006 Re: Array Slice Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep wrote:
>
> Pragma wrote:
>
>>...
>>
>>The only way to satisfy all of the above cleanly, is as a library type
>>that masquerades as an array. Something like a templated struct could
>>do the job nicely, and would cover more range types than just integer
>>sequences. In essence, I think the need for a range type w/array
>>semantics, is one-and-the-same with the need for an iterator
>>implementation. They're just two different flavors of the same thing:
>>one iterates an actual data set (which built-in arrays do implicitly),
>>the other pulls values out of thin air.
>
>
> Which brings up an interesting idea...
>
>
>>auto range = new Range!(int)(0,10,2); // 0-10 with 2 step
>>auto evens = someArray[range]; // extract even elements
>
>
> Would be really cool since you could fiddle with the range to get
> exactly the set of elements you want, and then extract them all in one
> pass. But if you're going to do that, why not just allow the "range"
> bit be any old iterator that iterates over keys?
>
>
>>auto range = AllPeople.marriedIterator;
>>auto shackled = AllPeople[range];
>
>
> Just a thought :3 Maybe we should just MAKE a library implementation of
> a range, hand it to Walter and say "let's make this standard".
>
> We can then write mixins to be used by library code for using ranges
> inside of opIndex; it should be possible to express opIndex(range) in
> terms of opIndex(key). Maybe if we can a standard iterator
> interface/base class/whatever, we can do the same to allow for slicing
> using an interator.
>
> (Also thinking out loud...)
My gut is listening, and it's starting to feel pretty good!
|
November 12, 2006 Re: Array Slice Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mariano | Mariano wrote:
> == Quote from %u (trevorparscal@hotmail.com)'s article
>> I'm learning ruby right now, and I noticed they use a very cool
> syntax for ranges.
>> 0..5 means 0, 1, 2, 3, 4, 5
>> 0...5 means 0, 1, 2, 3, 4
>> The current array slicing is useful half the time and a pain in the
> arse the
>> other half, so I was wondering if anyone else has mentioned this
> idea for D
>> before...
>> - Trevor
>
> Well, the difference is that in D 0..5 doesn't mean 0,1,2,3,4,5, but
> 'starting from 0, 5 positions'.
No, in D a..b means "starting from a go while less than b".
--bb
|
Copyright © 1999-2021 by the D Language Foundation