digitalmars.D.learn - Associative array and ranges
- Nrgyzer (10/10) Feb 02 2011 Hey guys,
- Simen kjaeraas (14/24) Feb 02 2011 You should probably try aa.byValue:
- Jonathan M Davis (9/22) Feb 02 2011 If you know which keys you want, then just have a list of those and iter...
- bearophile (4/9) Feb 02 2011 Show a hypothetical code example of what you desire to do, please.
- Nrgyzer (23/32) Feb 03 2011 there is
- Steven Schveighoffer (9/41) Feb 03 2011 First, hashes are not stored in any particular order, so I'm not sure wh...
- Nrgyzer (16/65) Feb 03 2011 array
- Steven Schveighoffer (17/82) Feb 03 2011 The AA does not do that. Note that there is no builtin 'set' type in D ...
- Nrgyzer (6/89) Feb 03 2011 I already thought about using an dynamic array like T[] (which contains ...
- Stanislav Blinov (12/21) Feb 03 2011 Why can't you?
- Nrgyzer (12/35) Feb 03 2011 which contains
- Stanislav Blinov (9/44) Feb 03 2011 There is no possible simplier way of removing an arbitrary element from
- bearophile (4/12) Feb 03 2011 ~ performs a memory allocation, while generally moving items inside an a...
- Stanislav Blinov (2/12) Feb 03 2011 Certainly. Forgot to mention that, thanks.
- Stanislav Blinov (3/19) Feb 03 2011 Hmm... Come to think of it, is it ever bad to memmove a reference? I
- spir (9/74) Feb 03 2011 Ruby hashes are like that, but I don't think it would be easy to do in D...
- spir (8/10) Feb 03 2011 Maybe what he needs is a plain Lisp-like symbol table (in D, an array of...
- Steven Schveighoffer (15/25) Feb 03 2011 dcollections contains more functionality than builtin AAs. The equivale...
Hey guys, I have an associative array like this: T[hash_t] myArray; (T means the template type). Is there any chance to cast/convert this array to an indexed array or is it possible to iterate over specific indices? I know that there is something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way. It's for a game and I think every next()-call influences the fps. I hope there is any solution for my problem :) - Thanks!
Feb 02 2011
Nrgyzer <nrgyzer gmail.com> wrote:Hey guys, I have an associative array like this: T[hash_t] myArray; (T means the template type). Is there any chance to cast/convert this array to an indexed array or is it possible to iterate over specific indices? I know that there is something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way. It's for a game and I think every next()-call influences the fps. I hope there is any solution for my problem :) - Thanks!You should probably try aa.byValue: auto o = ["a": 1, "b": 2]; foreach ( e; o.byValue ) { writeln( e ); } It seems from the (somewhat unreadable) source, that the values are stored in an array of pointers to structs holding these values. If this is not fast enough for your needs, I'm afraid you will have to write an AA implementation yourself. (You can replace the code in druntime/src/rt/aaA.d with your own if you still want the nice syntax sugar) -- Simen
Feb 02 2011
On Wednesday 02 February 2011 02:11:34 Nrgyzer wrote:Hey guys, I have an associative array like this: T[hash_t] myArray; (T means the template type). Is there any chance to cast/convert this array to an indexed array or is it possible to iterate over specific indices? I know that there is something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way. It's for a game and I think every next()-call influences the fps. I hope there is any solution for my problem :) - Thanks!If you know which keys you want, then just have a list of those and iterate over them, and then use them to grab their corresponding values from the AA on each iteration. As far as iterating over the AA itself goes, either you're iterating over the keys, the values, or both. You can't iterate over just part of it. I haven't a clue how such a thing would be implemented anyway. But there's nothing to stop you from iterating over a list of the keys that you want and then using those keys to grab the values from the AA. - Jonathan M Davis
Feb 02 2011
Nrgyzer:Is there any chance to cast/convert this array to an indexed array or is it possible to iterate over specific indices? I know that there is something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way.Show a hypothetical code example of what you desire to do, please. Bye, bearophile
Feb 02 2011
== Auszug aus bearophile (bearophileHUGS lycos.com)'s ArtikelNrgyzer:array orIs there any chance to cast/convert this array to an indexedthere isis it possible to iterate over specific indices? I know thatExample: ... class Example(T : Drawable) : Drawable { T[hash_t] pObjectsToDraw; uint pFrom, pTo; void setLimit(from, to) { pFrom = from; pTo = to; } void remove(T objToRemove) { pObjectsToDraw.remove(objToRemove.toHash()); } override void draw() { for (uint i = pFrom; i < pTo; i++) { pOjectsToDraw[i].draw(); // cannot call because pObjectsToDraw is an associative and no static or dynamic array } } }something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way.Show a hypothetical code example of what you desire to do, please. Bye, bearophile
Feb 03 2011
On Thu, 03 Feb 2011 09:35:44 -0500, Nrgyzer <nrgyzer gmail.com> wrote:== Auszug aus bearophile (bearophileHUGS lycos.com)'s ArtikelFirst, hashes are not stored in any particular order, so I'm not sure what you expect to accomplish except "give me (pTo - pFrom) random elements from the array" Second, you can use a foreach loop to get data out of an AA, and then break when you've retrieved enough elements. Again, I'm not sure what the point is of starting in the middle of the array. Are you expecting something different from a hashtable? -SteveNrgyzer:array orIs there any chance to cast/convert this array to an indexedthere isis it possible to iterate over specific indices? I know thatExample: ... class Example(T : Drawable) : Drawable { T[hash_t] pObjectsToDraw; uint pFrom, pTo; void setLimit(from, to) { pFrom = from; pTo = to; } void remove(T objToRemove) { pObjectsToDraw.remove(objToRemove.toHash()); } override void draw() { for (uint i = pFrom; i < pTo; i++) { pOjectsToDraw[i].draw(); // cannot call because pObjectsToDraw is an associative and no static or dynamic array } } }something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way.Show a hypothetical code example of what you desire to do, please. Bye, bearophile
Feb 03 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Thu, 03 Feb 2011 09:35:44 -0500, Nrgyzer <nrgyzer gmail.com>wrote:array== Auszug aus bearophile (bearophileHUGS lycos.com)'s ArtikelNrgyzer:array orIs there any chance to cast/convert this array to an indexedthere isis it possible to iterate over specific indices? I know thatsomething like next() for the foreach-statement but when the(forcontains some thousand instances and I only want iterate overplease.example) 5 elements I think that's the wrong way.Show a hypothetical code example of what you desire to do,sure whatFirst, hashes are not stored in any particular order, so I'm notBye, bearophileExample: ... class Example(T : Drawable) : Drawable { T[hash_t] pObjectsToDraw; uint pFrom, pTo; void setLimit(from, to) { pFrom = from; pTo = to; } void remove(T objToRemove) { pObjectsToDraw.remove(objToRemove.toHash()); } override void draw() { for (uint i = pFrom; i < pTo; i++) { pOjectsToDraw[i].draw(); // cannot call because pObjectsToDraw is an associative and no static or dynamic array } } }you expect to accomplish except "give me (pTo - pFrom) randomelementsfrom the array" Second, you can use a foreach loop to get data out of an AA, andthenbreak when you've retrieved enough elements. Again, I'm not sure what the point is of starting in the middle ofthearray. Are you expecting something different from a hashtable? -SteveI know that hashes aren't stored in any order... but lets take the LinkedHashSet in Java. The LinkedHashSet/Map stores the hashes in order of inserting. With the toArray()-method I can loop over specific elements/indices... but I can also remove the elements by their hash. I'm looking for a similar technique in D - you can find an Java example on http://www.java2s.com/Code/JavaAPI/java.util/ LinkedHashSettoArray.htm.
Feb 03 2011
On Thu, 03 Feb 2011 10:41:16 -0500, Nrgyzer <nrgyzer gmail.com> wrote:== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelThe AA does not do that. Note that there is no builtin 'set' type in D (there is one in dcollections). Note that your worry about performance when iterating the AA is completely negated by the toArray call -- this allocates space for your temporary array, and necessarily iterates all elements, even if you only want 5. You are better off not to do things this way. Incidentally, I do plan on adding a Link*Set/Map to dcollections, because I really like the array type in php (same thing). But this will not provide constant access to the nth element, so it still will fail your requirements. The only thing I can think of is to store the elements in an array alongside the hash map (do you need to look up elements by hash_t? If not, why not just use an array directly?) to store the order of insertion. This only works if you rarely remove elements (removal in an array is an O(n) operation). -SteveOn Thu, 03 Feb 2011 09:35:44 -0500, Nrgyzer <nrgyzer gmail.com>wrote:array== Auszug aus bearophile (bearophileHUGS lycos.com)'s ArtikelNrgyzer:array orIs there any chance to cast/convert this array to an indexedthere isis it possible to iterate over specific indices? I know thatsomething like next() for the foreach-statement but when the(forcontains some thousand instances and I only want iterate overplease.example) 5 elements I think that's the wrong way.Show a hypothetical code example of what you desire to do,sure whatFirst, hashes are not stored in any particular order, so I'm notBye, bearophileExample: ... class Example(T : Drawable) : Drawable { T[hash_t] pObjectsToDraw; uint pFrom, pTo; void setLimit(from, to) { pFrom = from; pTo = to; } void remove(T objToRemove) { pObjectsToDraw.remove(objToRemove.toHash()); } override void draw() { for (uint i = pFrom; i < pTo; i++) { pOjectsToDraw[i].draw(); // cannot call because pObjectsToDraw is an associative and no static or dynamic array } } }you expect to accomplish except "give me (pTo - pFrom) randomelementsfrom the array" Second, you can use a foreach loop to get data out of an AA, andthenbreak when you've retrieved enough elements. Again, I'm not sure what the point is of starting in the middle ofthearray. Are you expecting something different from a hashtable? -SteveI know that hashes aren't stored in any order... but lets take the LinkedHashSet in Java. The LinkedHashSet/Map stores the hashes in order of inserting. With the toArray()-method I can loop over specific elements/indices... but I can also remove the elements by their hash. I'm looking for a similar technique in D - you can find an Java example on http://www.java2s.com/Code/JavaAPI/java.util/ LinkedHashSettoArray.htm.
Feb 03 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Thu, 03 Feb 2011 10:41:16 -0500, Nrgyzer <nrgyzer gmail.com> wrote:I already thought about using an dynamic array like T[] (which contains all elements that should be drawn) and a second like uint[hash_t] which contains the indices in the first array. But it does only shit the problem that I can't remove an index from a dynamic array. Thanks for your suggestions.== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelThe AA does not do that. Note that there is no builtin 'set' type in D (there is one in dcollections). Note that your worry about performance when iterating the AA is completely negated by the toArray call -- this allocates space for your temporary array, and necessarily iterates all elements, even if you only want 5. You are better off not to do things this way. Incidentally, I do plan on adding a Link*Set/Map to dcollections, because I really like the array type in php (same thing). But this will not provide constant access to the nth element, so it still will fail your requirements. The only thing I can think of is to store the elements in an array alongside the hash map (do you need to look up elements by hash_t? If not, why not just use an array directly?) to store the order of insertion. This only works if you rarely remove elements (removal in an array is an O(n) operation). -SteveOn Thu, 03 Feb 2011 09:35:44 -0500, Nrgyzer <nrgyzer gmail.com>wrote:array== Auszug aus bearophile (bearophileHUGS lycos.com)'s ArtikelNrgyzer:array orIs there any chance to cast/convert this array to an indexedthere isis it possible to iterate over specific indices? I know thatsomething like next() for the foreach-statement but when the(forcontains some thousand instances and I only want iterate overplease.example) 5 elements I think that's the wrong way.Show a hypothetical code example of what you desire to do,sure whatFirst, hashes are not stored in any particular order, so I'm notBye, bearophileExample: ... class Example(T : Drawable) : Drawable { T[hash_t] pObjectsToDraw; uint pFrom, pTo; void setLimit(from, to) { pFrom = from; pTo = to; } void remove(T objToRemove) { pObjectsToDraw.remove(objToRemove.toHash()); } override void draw() { for (uint i = pFrom; i < pTo; i++) { pOjectsToDraw[i].draw(); // cannot call because pObjectsToDraw is an associative and no static or dynamic array } } }you expect to accomplish except "give me (pTo - pFrom) randomelementsfrom the array" Second, you can use a foreach loop to get data out of an AA, andthenbreak when you've retrieved enough elements. Again, I'm not sure what the point is of starting in the middle ofthearray. Are you expecting something different from a hashtable? -SteveI know that hashes aren't stored in any order... but lets take the LinkedHashSet in Java. The LinkedHashSet/Map stores the hashes in order of inserting. With the toArray()-method I can loop over specific elements/indices... but I can also remove the elements by their hash. I'm looking for a similar technique in D - you can find an Java example on http://www.java2s.com/Code/JavaAPI/java.util/ LinkedHashSettoArray.htm.
Feb 03 2011
03.02.2011 19:34, Nrgyzer пишет:== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelWhy can't you? You can: 1) Get an index i from hash, do arr = arr[0..i] ~ arr[i+1..$] and then reindex all arr[i..$] elements. This is costly, because, as Steven mentioned, such removal is O(n) plus you have to iterate all elements with index >= i, and this traversal is O(n) in the worst case. 2) Use unstable removal. Since you store indices separately, you can just swap an element to be removed with last element in the array, shrink array using slicing (arr = arr[0..$-1]) and reindex a single element (the one that was previously last in the array). The drawback is that this approach doesn't preserve order of elements in the array.This only works if you rarely remove elements (removal in an array is an O(n) operation). -SteveI already thought about using an dynamic array like T[] (which contains all elements that should be drawn) and a second like uint[hash_t] which contains the indices in the first array. But it does only shit the problem that I can't remove an index from a dynamic array. Thanks for your suggestions.
Feb 03 2011
== Auszug aus Stanislav Blinov (blinov loniir.ru)'s Artikel03.02.2011 19:34, Nrgyzer пишет:contains all== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelThis only works if you rarely remove elements (removal in an array is an O(n) operation). -SteveI already thought about using an dynamic array like T[] (whichwhich containselements that should be drawn) and a second like uint[hash_t]that I can'tthe indices in the first array. But it does only shit the problemthenremove an index from a dynamic array. Thanks for your suggestions.Why can't you? You can: 1) Get an index i from hash, do arr = arr[0..i] ~ arr[i+1..$] andreindex all arr[i..$] elements. This is costly, because, as Steven mentioned, such removal is O(n) plus you have to iterate allelementswith index >= i, and this traversal is O(n) in the worst case. 2) Use unstable removal. Since you store indices separately, you can just swap an element to be removed with last element in the array, shrink array using slicing (arr = arr[0..$-1]) and reindex a single element (the one that was previously last in the array). Thedrawback isthat this approach doesn't preserve order of elements in the array.Ah, okay... I already tried some things with [0..i] ~ [i + 1..$] but there was always an error and I thought, it must be done more simply. I'm just using a simple, dynamic array and use a for-loop to remove them. I don't need remove() often, but I thought there is any way to do it in O(1).
Feb 03 2011
On 02/03/2011 08:01 PM, Nrgyzer wrote:== Auszug aus Stanislav Blinov (blinov loniir.ru)'s ArtikelThere is no possible simplier way of removing an arbitrary element from an array than doing that. Well, maybe there is: if your data is POD you could use a memmove with subsequent slice-shrink, but I see we're talking about storing references in this case.03.02.2011 19:34, Nrgyzer пишет:contains all== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelThis only works if you rarely remove elements (removal in an array is an O(n) operation). -SteveI already thought about using an dynamic array like T[] (whichwhich containselements that should be drawn) and a second like uint[hash_t]that I can'tthe indices in the first array. But it does only shit the problemthenremove an index from a dynamic array. Thanks for your suggestions.Why can't you? You can: 1) Get an index i from hash, do arr = arr[0..i] ~ arr[i+1..$] andreindex all arr[i..$] elements. This is costly, because, as Steven mentioned, such removal is O(n) plus you have to iterate allelementswith index>= i, and this traversal is O(n) in the worst case. 2) Use unstable removal. Since you store indices separately, you can just swap an element to be removed with last element in the array, shrink array using slicing (arr = arr[0..$-1]) and reindex a single element (the one that was previously last in the array). Thedrawback isthat this approach doesn't preserve order of elements in the array.Ah, okay... I already tried some things with [0..i] ~ [i + 1..$] but there was always an error and I thought, it must be done more simply.I'm just using a simple, dynamic array and use a for-loop to remove them. I don't need remove() often, but I thought there is any way to do it in O(1).Actually, method (2) is O(1) if you discount hash lookup and possible postblit (which is absent in case of references). You could even employ intrusive indexing (when objects store indices), if that is suitable for your application, thus discarding hash table entirely.
Feb 03 2011
Stanislav Blinov:Nrgyzer:~ performs a memory allocation, while generally moving items inside an array doesn't require it. Bye, bearophileAh, okay... I already tried some things with [0..i] ~ [i + 1..$] but there was always an error and I thought, it must be done more simply.There is no possible simplier way of removing an arbitrary element from an array than doing that. Well, maybe there is: if your data is POD you could use a memmove with subsequent slice-shrink, but I see we're talking about storing references in this case.
Feb 03 2011
On 02/04/2011 12:48 AM, bearophile wrote:Stanislav Blinov:Certainly. Forgot to mention that, thanks.Nrgyzer:~ performs a memory allocation, while generally moving items inside an array doesn't require it.Ah, okay... I already tried some things with [0..i] ~ [i + 1..$] but there was always an error and I thought, it must be done more simply.There is no possible simplier way of removing an arbitrary element from an array than doing that. Well, maybe there is: if your data is POD you could use a memmove with subsequent slice-shrink, but I see we're talking about storing references in this case.
Feb 03 2011
On 02/04/2011 01:19 AM, Stanislav Blinov wrote:On 02/04/2011 12:48 AM, bearophile wrote:Hmm... Come to think of it, is it ever bad to memmove a reference? I wouldn't think so. I think I got C++ classes in mind when I wrote that.Stanislav Blinov:Certainly. Forgot to mention that, thanks.Nrgyzer:~ performs a memory allocation, while generally moving items inside an array doesn't require it.Ah, okay... I already tried some things with [0..i] ~ [i + 1..$] but there was always an error and I thought, it must be done more simply.There is no possible simplier way of removing an arbitrary element from an array than doing that. Well, maybe there is: if your data is POD you could use a memmove with subsequent slice-shrink, but I see we're talking about storing references in this case.
Feb 03 2011
On 02/03/2011 04:41 PM, Nrgyzer wrote:== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelRuby hashes are like that, but I don't think it would be easy to do in D. You'd better maintain the insertion order yourself in a // array of keys, or make elements link list nodes. Denis -- _________________ vita es estrany spir.wikidot.comOn Thu, 03 Feb 2011 09:35:44 -0500, Nrgyzer<nrgyzer gmail.com>wrote:array== Auszug aus bearophile (bearophileHUGS lycos.com)'s ArtikelNrgyzer:array orIs there any chance to cast/convert this array to an indexedthere isis it possible to iterate over specific indices? I know thatsomething like next() for the foreach-statement but when the(forcontains some thousand instances and I only want iterate overplease.example) 5 elements I think that's the wrong way.Show a hypothetical code example of what you desire to do,sure whatFirst, hashes are not stored in any particular order, so I'm notBye, bearophileExample: ... class Example(T : Drawable) : Drawable { T[hash_t] pObjectsToDraw; uint pFrom, pTo; void setLimit(from, to) { pFrom = from; pTo = to; } void remove(T objToRemove) { pObjectsToDraw.remove(objToRemove.toHash()); } override void draw() { for (uint i = pFrom; i< pTo; i++) { pOjectsToDraw[i].draw(); // cannot call because pObjectsToDraw is an associative and no static or dynamic array } } }you expect to accomplish except "give me (pTo - pFrom) randomelementsfrom the array" Second, you can use a foreach loop to get data out of an AA, andthenbreak when you've retrieved enough elements. Again, I'm not sure what the point is of starting in the middle ofthearray. Are you expecting something different from a hashtable? -SteveI know that hashes aren't stored in any order... but lets take the LinkedHashSet in Java. The LinkedHashSet/Map stores the hashes in order of inserting. With the toArray()-method I can loop over specific elements/indices... but I can also remove the elements by their hash. I'm looking for a similar technique in D - you can find an Java example on http://www.java2s.com/Code/JavaAPI/java.util/ LinkedHashSettoArray.htm.
Feb 03 2011
On 02/03/2011 04:29 PM, Steven Schveighoffer wrote:Again, I'm not sure what the point is of starting in the middle of the array. Are you expecting something different from a hashtable?Maybe what he needs is a plain Lisp-like symbol table (in D, an array of (key value) pairs)? Denis -- _________________ vita es estrany spir.wikidot.com
Feb 03 2011
On Wed, 02 Feb 2011 05:11:34 -0500, Nrgyzer <nrgyzer gmail.com> wrote:Hey guys, I have an associative array like this: T[hash_t] myArray; (T means the template type). Is there any chance to cast/convert this array to an indexed array or is it possible to iterate over specific indices? I know that there is something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way. It's for a game and I think every next()-call influences the fps. I hope there is any solution for my problem :) - Thanks!dcollections contains more functionality than builtin AAs. The equivalent type in dcollections would be HashMap!(hash_t, T): http://www.dsource.org/projects/dcollections You might find this helps solve some problems. I don't really understand what you are asking for, if you want to iterate over "specific" indexes, wouldn't you just use those indexes to look up the elements you desire? i.e.: foreach(i; specific_indexes) // specific_indexes is an array of the indexes you wish to use { auto elem = myArray[i]; ... } -Steve
Feb 03 2011