digitalmars.D - extend "in" to all array types
- pplantinga (6/6) Jan 15 2014 In python, I really like the ability to check if an element is in
- Adam D. Ruppe (20/21) Jan 15 2014 Probably not, since there's a significant speed difference
- John Colvin (6/28) Jan 15 2014 or:
- Meta (3/40) Jan 15 2014 Programming in D is constantly mind-blowing as you realize how
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/7) Jan 15 2014 And a specialization for std.range.SortedRange would use binary search:
- H. S. Teoh (7/16) Jan 15 2014 [...]
- Jakob Ovrum (5/9) Jan 15 2014 Not yet, SortedRange could need some attention. Judging by a
- Jakob Ovrum (7/17) Jan 15 2014 I'm for it, but it would have to have the explicit caveat that it
- John Colvin (23/29) Jan 15 2014 import std.algorithm: canFind;
- Meta (31/62) Jan 15 2014 auto inWrap(T)(T[] arr)
- Tobias Pankrath (3/33) Jan 15 2014 The in-operator should return T* for consistency with the
- Namespace (26/65) Jan 15 2014 That was exactly my thoughts:
- Jakob Ovrum (4/5) Jan 15 2014 This is gratuitous operator overloading. We have
- Brad Anderson (5/44) Jan 15 2014 I was thinking recently it'd be even more convenient if it
- luka8088 (2/9) Jan 15 2014 D array uses this operator for checking against array keys, not values.
- Jakob Ovrum (4/16) Jan 16 2014 It makes sense for sorted arrays, as they make good sets.
In python, I really like the ability to check if an element is in an array: if x in array: D has this, but only for associative arrays. Is there any chance we could extend this to every kind of array?
Jan 15 2014
On Wednesday, 15 January 2014 at 15:30:35 UTC, pplantinga wrote:Is there any chance we could extend this to every kind of array?Probably not, since there's a significant speed difference between in associative array and in regular array. For a regular array, it means potentially looping over every item in the array. As a general rule, D likes to make long loops obvious in some way, like a different function name. There are functions which do the same thing. Notably, std.algorithm.canFind import std.algorithm; if(array.canFind(x)) { /* do something */ } You could also define your own function In if you wanted to keep the order that way: bool In(T)(T lookFor, T[] lookIn) { import std.algorithm; return lookIn.canFind(lookFor); } if(x.In(array)) { /* do something */ } It is capitalized so it doesn't clash with the keyword, and still uses the dot - it is a function called with dot syntax instead of an operator - but it works.
Jan 15 2014
On Wednesday, 15 January 2014 at 15:38:19 UTC, Adam D. Ruppe wrote:On Wednesday, 15 January 2014 at 15:30:35 UTC, pplantinga wrote:or: import std.functional : binaryReverseArgs; import std.algorithm : canFind; alias In = binaryReverseArgs!canFind;Is there any chance we could extend this to every kind of array?Probably not, since there's a significant speed difference between in associative array and in regular array. For a regular array, it means potentially looping over every item in the array. As a general rule, D likes to make long loops obvious in some way, like a different function name. There are functions which do the same thing. Notably, std.algorithm.canFind import std.algorithm; if(array.canFind(x)) { /* do something */ } You could also define your own function In if you wanted to keep the order that way: bool In(T)(T lookFor, T[] lookIn) { import std.algorithm; return lookIn.canFind(lookFor); } if(x.In(array)) { /* do something */ } It is capitalized so it doesn't clash with the keyword, and still uses the dot - it is a function called with dot syntax instead of an operator - but it works.
Jan 15 2014
On Wednesday, 15 January 2014 at 15:51:06 UTC, John Colvin wrote:On Wednesday, 15 January 2014 at 15:38:19 UTC, Adam D. Ruppe wrote:Programming in D is constantly mind-blowing as you realize how powerful the language is.On Wednesday, 15 January 2014 at 15:30:35 UTC, pplantinga wrote:or: import std.functional : binaryReverseArgs; import std.algorithm : canFind; alias In = binaryReverseArgs!canFind;Is there any chance we could extend this to every kind of array?Probably not, since there's a significant speed difference between in associative array and in regular array. For a regular array, it means potentially looping over every item in the array. As a general rule, D likes to make long loops obvious in some way, like a different function name. There are functions which do the same thing. Notably, std.algorithm.canFind import std.algorithm; if(array.canFind(x)) { /* do something */ } You could also define your own function In if you wanted to keep the order that way: bool In(T)(T lookFor, T[] lookIn) { import std.algorithm; return lookIn.canFind(lookFor); } if(x.In(array)) { /* do something */ } It is capitalized so it doesn't clash with the keyword, and still uses the dot - it is a function called with dot syntax instead of an operator - but it works.
Jan 15 2014
On 01/15/2014 07:38 AM, Adam D. Ruppe wrote:Probably not, since there's a significant speed difference between in associative array and in regular array. For a regular array, it means potentially looping over every item in the array.And a specialization for std.range.SortedRange would use binary search: Ali
Jan 15 2014
On Wed, Jan 15, 2014 at 10:57:14AM -0800, Ali Çehreli wrote:On 01/15/2014 07:38 AM, Adam D. Ruppe wrote:[...] Does std.algorithm.find have a specialization for SortedRange? I know that some algorithms do, I just don't remember which. T -- What do you get if you drop a piano down a mineshaft? A flat minor.Probably not, since there's a significant speed difference between in associative array and in regular array. For a regular array, it means potentially looping over every item in the array.And a specialization for std.range.SortedRange would use binary search:
Jan 15 2014
On Wednesday, 15 January 2014 at 19:10:27 UTC, H. S. Teoh wrote:Does std.algorithm.find have a specialization for SortedRange? I know that some algorithms do, I just don't remember which. TNot yet, SortedRange could need some attention. Judging by a certain old but recently relevant pull request[1], I think Andrei has some work on it. [1] https://github.com/D-Programming-Language/phobos/pull/1184
Jan 15 2014
On Wednesday, 15 January 2014 at 18:57:15 UTC, Ali Çehreli wrote:On 01/15/2014 07:38 AM, Adam D. Ruppe wrote:I'm for it, but it would have to have the explicit caveat that it would only return a pointer to the *first* equal element in the list, as there may be duplicates. If we instead return a range, then suddenly we have `std.algorithm.find`. Maybe `findSplit` should also have a specialization for `SortedRange` that uses `SortedRange.trisect`.Probably not, since there's a significant speed differencebetween inassociative array and in regular array. For a regular array,it meanspotentially looping over every item in the array.And a specialization for std.range.SortedRange would use binary search: Ali
Jan 15 2014
On Wednesday, 15 January 2014 at 15:30:35 UTC, pplantinga wrote:In python, I really like the ability to check if an element is in an array: if x in array: D has this, but only for associative arrays. Is there any chance we could extend this to every kind of array?import std.algorithm: canFind; if(array.canFind(x)) //do something alternatively, something like this: struct InWrapper(T) { T unwrapped; alias unwrapped this; auto opBinaryRight(string op, T)(T el) if(op == "in") { import std.algorithm : canFind; return unwrapped.canFind(el); } } unittest { InWrapper!(int[]) arr; arr = [1,2,3,4]; assert(4 in arr); assert(!(5 in arr)); }
Jan 15 2014
On Wednesday, 15 January 2014 at 15:48:13 UTC, John Colvin wrote:On Wednesday, 15 January 2014 at 15:30:35 UTC, pplantinga wrote:auto inWrap(T)(T[] arr) { static struct InWrapper { import std.typecons: Nullable; private T[] payload; Nullable!size_t opBinaryRight(string op: "in")(T val) { Nullable!size_t index; foreach (i, element; payload) { if (element == val) { index = i; return index; } } return index; } } return InWrapper(arr); } void main() { auto arr = [0, 1, 2, 3, 4]; auto i = 2 in arr.inWrap; assert(!i.isNull); assert(i == 2); }In python, I really like the ability to check if an element is in an array: if x in array: D has this, but only for associative arrays. Is there any chance we could extend this to every kind of array?import std.algorithm: canFind; if(array.canFind(x)) //do something alternatively, something like this: struct InWrapper(T) { T unwrapped; alias unwrapped this; auto opBinaryRight(string op, T)(T el) if(op == "in") { import std.algorithm : canFind; return unwrapped.canFind(el); } } unittest { InWrapper!(int[]) arr; arr = [1,2,3,4]; assert(4 in arr); assert(!(5 in arr)); }
Jan 15 2014
On Wednesday, 15 January 2014 at 17:13:37 UTC, Meta wrote:auto inWrap(T)(T[] arr) { static struct InWrapper { import std.typecons: Nullable; private T[] payload; Nullable!size_t opBinaryRight(string op: "in")(T val) { Nullable!size_t index; foreach (i, element; payload) { if (element == val) { index = i; return index; } } return index; } } return InWrapper(arr); } void main() { auto arr = [0, 1, 2, 3, 4]; auto i = 2 in arr.inWrap; assert(!i.isNull); assert(i == 2); }The in-operator should return T* for consistency with the build-in ones.
Jan 15 2014
On Wednesday, 15 January 2014 at 17:29:07 UTC, Tobias Pankrath wrote:On Wednesday, 15 January 2014 at 17:13:37 UTC, Meta wrote:That was exactly my thoughts: ---- auto each(T)(T[] arr) pure nothrow { static struct InWrapper { private T[] payload; T* opBinaryRight(string op : "in")(T val) pure nothrow { foreach (ref T element; payload) { if (element == val) return &element; } return null; } } return InWrapper(arr); } void main() { int[] arr = [0, 1, 2, 3, 4]; auto i = 2 in arr.each; assert(i !is null); assert(*i == 2); } ---- Something like that should really be in std.array.auto inWrap(T)(T[] arr) { static struct InWrapper { import std.typecons: Nullable; private T[] payload; Nullable!size_t opBinaryRight(string op: "in")(T val) { Nullable!size_t index; foreach (i, element; payload) { if (element == val) { index = i; return index; } } return index; } } return InWrapper(arr); } void main() { auto arr = [0, 1, 2, 3, 4]; auto i = 2 in arr.inWrap; assert(!i.isNull); assert(i == 2); }The in-operator should return T* for consistency with the build-in ones.
Jan 15 2014
On Wednesday, 15 January 2014 at 17:33:27 UTC, Namespace wrote:Something like that should really be in std.array.This is gratuitous operator overloading. We have std.algorithm.find that does this in an equally powerful but more transparent way.
Jan 15 2014
On Wednesday, 15 January 2014 at 17:29:07 UTC, Tobias Pankrath wrote:On Wednesday, 15 January 2014 at 17:13:37 UTC, Meta wrote:I was thinking recently it'd be even more convenient if it returned std.typecons.Nullable. Then you get alias this and aren't having to constantly dereference it yourself.auto inWrap(T)(T[] arr) { static struct InWrapper { import std.typecons: Nullable; private T[] payload; Nullable!size_t opBinaryRight(string op: "in")(T val) { Nullable!size_t index; foreach (i, element; payload) { if (element == val) { index = i; return index; } } return index; } } return InWrapper(arr); } void main() { auto arr = [0, 1, 2, 3, 4]; auto i = 2 in arr.inWrap; assert(!i.isNull); assert(i == 2); }The in-operator should return T* for consistency with the build-in ones.
Jan 15 2014
On 15.1.2014. 16:30, pplantinga wrote:In python, I really like the ability to check if an element is in an array: if x in array: D has this, but only for associative arrays. Is there any chance we could extend this to every kind of array?D array uses this operator for checking against array keys, not values.
Jan 15 2014
On Thursday, 16 January 2014 at 07:28:43 UTC, luka8088 wrote:On 15.1.2014. 16:30, pplantinga wrote:It makes sense for sorted arrays, as they make good sets. That said, it makes the most sense to limit opBinaryRight!"in" to SortedRange.In python, I really like the ability to check if an element is in an array: if x in array: D has this, but only for associative arrays. Is there any chance we could extend this to every kind of array?D array uses this operator for checking against array keys, not values.
Jan 16 2014