From: Martin DeMello Date: 2012-05-02T13:38:25+09:00 Subject: Re: Overwriting one Ruby array or arrays with another On Tue, May 1, 2012 at 9:14 PM, Craig Law wrote: > Martin > > Just as a matter of interest if I was forced to continue using an array > of arrays such as [1, 1, "X", "20120502"] what would be the most > efficient way of overwriting the array with another array as described > in my second post (the only reason I ask is that my code at the moment > is spitting out an array of arrays and I'm going to have to work out how > to spit out the hashes in an ordered manner to use the more efficient > has method you've described). Can I use a similar update method as > you've done with hashes? No, it's a bit more work if you want to use arrays that way, since you don't have a trivial "find the cell with coordinates x, y" method. Assuming that arrays a and b are sorted first by x and then by y, you could write a helper method that did a binary search on array a (as a side note, ruby does implement < and > for arrays, and the elements are compared pairwise starting from the first one), and then say def find_in_grid(array, x, y) # return the index of the cell starting [x, y, ...] if it is found, otherwise nil end b.each do |cell| index = find_in_grid(a, cell[0], cell[1]) if index a[index] = cell end end find_in_grid can be implemented using a binary search, or you could maintain some sort of (e.g. pointers to the start of each grid row) if you want to update it frequently. Also, note that if there is an (x, y) in b that is *not* in a, inserting it will be an additional problem since you have to maintain the sorted order and inserting into the middle of an array is relatively expensive. Of course, all this might just be premature optimisation - if the grid update is not slowing your code down, do the simplest thing that could work, which is convert a and b into hashes, update, and then convert back into an array. (It might even be the fastest thing to do, if you have a dense grid and a lot of updates). To convert an array to a hash: hash = {} a.each do |cell| x, y, *rest = cell hash[[x, y]] = rest end and back: hash.keys.sort.map {|k| [k] + hash[k]} Where sorting the keys of the hash ensures that your array is spat out in the proper order. martin