What's the difference between arrays and hashes? - ruby-on-rails

What's the difference between arrays and hashes in Ruby?

From Ruby-Doc:
Arrays are ordered, integer-indexed collections of any object. Array indexing starts at 0, as in C or Java. A negative index is assumed to be relative to the end of the array—that is, an index of -1 indicates the last element of the array, -2 is the next to last element in the array, and so on. Look here for more.
A Hash is a collection of key-value pairs. It is similar to an Array, except that indexing is done via arbitrary keys of any object type, not an integer index. Hashes enumerate their values in the order that the corresponding keys were inserted.
Hashes have a default value that is returned when accessing keys that do not exist in the hash. By default, that value is nil. Look here for more.

Arrays:
Arrays are used to store collections of data. Each object in an array has an unique key assigned to it. We can access any object in the array using this unique key. The positions in an array starts from " 0 ". The first element is located at " 0 ", the second at 1st position etc.
Example:
Try the following in - irb.
bikes = Array.new
bikes = %w[Bajaj-Pulsar, Honda-Unicorn, TVS-Apache, Yamaha, Suzuki]
You have added 4 elements in the array.
puts bikes[3]
Yamaha,
Add a new element to position 5.
bikes[5] = "Hardly Davidson"
Hashes:
Like arrays, Hashes are also used to store data. Hashes points an object to another object. Consider of assigning a certain "meaning" to a string. Each time you refer that string, it refers its "meaning".
Example:
bikes = Hash.new
bikes = {
'Bajaj' => 'Pulsar 220, Pulsar 200, Pulsar 180 and Pulsar 150',
'Honda' => 'Unicorn, Shine and Splendor',
'TVS' => 'Apache, Star City, and Victor'
}
Try this now:
bikes['Bajaj']
You get => "Pulsar 220, Pulsar 200, Pulsar 180 and Pulsar 150"

An array is an ordered list of things: a, b, c, d
A hash is a collection of key/value pairs: john has a peugeot, bob has a renault, adam has a ford.

The two terms get "hashed" together these days. I think this is how it goes:
A "hash" will have key -> value pairs:
(top -> tshirt, bottom -> shorts, feet -> shoes)
And an "array" will typically have an index:
([0]tshirt, [1]shorts, [2]shoes)
But, right or wrong, you'll see things with key -> value pairs called "arrays", too.
I think the difference depends mainly on when and how you want to use them. You won't get into much trouble calling an array a hash, or vice versa, but you should know the difference.

Related

LuA How to sort table from lowest value without key changes [duplicate]

I have a key => value table I'd like to sort in Lua. The keys are all integers, but aren't consecutive (and have meaning). Lua's only sort function appears to be table.sort, which treats tables as simple arrays, discarding the original keys and their association with particular items. Instead, I'd essentially like to be able to use PHP's asort() function.
What I have:
items = {
[1004] = "foo",
[1234] = "bar",
[3188] = "baz",
[7007] = "quux",
}
What I want after the sort operation:
items = {
[1234] = "bar",
[3188] = "baz",
[1004] = "foo",
[7007] = "quux",
}
Any ideas?
Edit: Based on answers, I'm going to assume that it's simply an odd quirk of the particular embedded Lua interpreter I'm working with, but in all of my tests, pairs() always returns table items in the order in which they were added to the table. (i.e. the two above declarations would iterate differently).
Unfortunately, because that isn't normal behavior, it looks like I can't get what I need; Lua doesn't have the necessary tools built-in (of course) and the embedded environment is too limited for me to work around it.
Still, thanks for your help, all!
You seem to misunderstand something. What you have here is a associative array. Associative arrays have no explicit order on them, e.g. it's only the internal representation (usually sorted) that orders them.
In short -- in Lua, both of the arrays you posted are the same.
What you would want instead, is such a representation:
items = {
{1004, "foo"},
{1234, "bar"},
{3188, "baz"},
{7007, "quux"},
}
While you can't get them by index now (they are indexed 1, 2, 3, 4, but you can create another index array), you can sort them using table.sort.
A sorting function would be then:
function compare(a,b)
return a[1] < b[1]
end
table.sort(items, compare)
As Komel said, you're dealing with associative arrays, which have no guaranteed ordering.
If you want key ordering based on its associated value while also preserving associative array functionality, you can do something like this:
function getKeysSortedByValue(tbl, sortFunction)
local keys = {}
for key in pairs(tbl) do
table.insert(keys, key)
end
table.sort(keys, function(a, b)
return sortFunction(tbl[a], tbl[b])
end)
return keys
end
items = {
[1004] = "foo",
[1234] = "bar",
[3188] = "baz",
[7007] = "quux",
}
local sortedKeys = getKeysSortedByValue(items, function(a, b) return a < b end)
sortedKeys is {1234,3188,1004,7007}, and you can access your data like so:
for _, key in ipairs(sortedKeys) do
print(key, items[key])
end
result:
1234 bar
3188 baz
1004 foo
7007 quux
hmm, missed the part about not being able to control the iteration. there
But in lua there is usually always a way.
http://lua-users.org/wiki/OrderedAssociativeTable
Thats a start. Now you would need to replace the pairs() that the library uses. That could be a simples as pairs=my_pairs. You could then use the solution in the link above
PHP arrays are different from Lua tables.
A PHP array may have an ordered list of key-value pairs.
A Lua table always contains an unordered set of key-value pairs.
A Lua table acts as an array when a programmer chooses to use integers 1, 2, 3, ... as keys. The language syntax and standard library functions, like table.sort offer special support for tables with consecutive-integer keys.
So, if you want to emulate a PHP array, you'll have to represent it using list of key-value pairs, which is really a table of tables, but it's more helpful to think of it as a list of key-value pairs. Pass a custom "less-than" function to table.sort and you'll be all set.
N.B. Lua allows you to mix consecutive-integer keys with any other kinds of keys in the same table—and the representation is efficient. I use this feature sometimes, usually to tag an array with a few pieces of metadata.
Coming to this a few months later, with the same query. The recommended answer seemed to pinpoint the gap between what was required and how this looks in LUA, but it didn't get me what I was after exactly :- which was a Hash sorted by Key.
The first three functions on this page DID however : http://lua-users.org/wiki/SortedIteration
I did a brief bit of Lua coding a couple of years ago but I'm no longer fluent in it.
When faced with a similar problem, I copied my array to another array with keys and values reversed, then used sort on the new array.
I wasn't aware of a possibility to sort the array using the method Kornel Kisielewicz recommends.
The proposed compare function works but only if the values in the first column are unique.
Here is a bit enhanced compare function to ensure, if the values of a actual column equals, it takes values from next column to evaluate...
With {1234, "baam"} < {1234, "bar"} to be true the items the array containing "baam" will be inserted before the array containing the "bar".
local items = {
{1004, "foo"},
{1234, "bar"},
{1234, "baam"},
{3188, "baz"},
{7007, "quux"},
}
local function compare(a, b)
for inx = 1, #a do
-- print("A " .. inx .. " " .. a[inx])
-- print("B " .. inx .. " " .. b[inx])
if a[inx] == b[inx] and a[inx + 1] < b[inx + 1] then
return true
elseif a[inx] ~= b[inx] and a[inx] < b[inx] == true then
return true
else
return false
end
end
return false
end
table.sort(items,compare)

Active Record Array array query - to check records that are present in an array

I have an Objective model which has an attribute called as labels whose values are array data type. I need to query all the Objectives whose labels attribute has values that are present in some particular array.
For Example:
I have an array
a = ["textile", "blazer"]
the Objective.labels may have values as ["textile, "ramen"]
I need to return all objectives that might have either "textile" or "blazer" as one of their labels array values
I tried the following:
Objective.where("labels #> ARRAY[?]::varchar[]", ["textile"])
This returns some records.Now when I try
Objective.where("labels #> ARRAY[?]::varchar[]", ["textile", "Blazer"])
I expect it to return all Objectives which contains at-least one of the labels array value as textile or blazer.
However, it returns an empty array. Any Solutions?
Try && overlap operator.
overlap (have elements in common)
Objective.where("labels && ARRAY[?]::varchar[]", ["textile", "Blazer"])
If you have many rows, a GIN index can speed it up.

Understanding GameMonkey Script Mixed Arrays

I was just reading some introductory stuff from GameMonkey Script on https://www.gamedev.net/articles/programming/engines-and-middleware/introduction-to-gamemonkey-script-r3297/ and when they were explaining about Mixed Arrays they say that you can access the elements using and index or a key depending on how the value was declared, so for example if i have the next array
myMixedArray = table( 1, 3, 4, KeyV = "Test", 33);
then i can access 1, 2, 4 and 33 using the next indices 0, 1, 2, 3 and
to access "Test" i'll do it like this
myMixedArray["KeyV"] <- ("Test")
now according with the following image that you can find in the above link
The number expected to be at myTest[3] is 7, but that would mean that both regular values and key-val elements are not really separated in the array.
If not then why would 7 be at the index 3 of the array?
While you can treat a gm Table as an Array or Map, you can't effectively do both at the same time.
Internally, the Table is just a hash table, and your index access method is a bit like an iterator.
In your example, because value "Test" is assigned to key 'KeyV', it messes up the otherwise contiguous index order.
Hopefully that gives you an idea of the cause. Try iterating a table with no 'keys' and again with all key value pairs. Observe the different behavior.
If you are serious about arrays, you may be better off using a binding to create an Array type with the behavior you want. GM source has an example of an array container.

How to work with tables in Corona SDK

I have a sort of general question but i think that if I tried to be too specific I would only make it very confusing. So basically what I want to know is this:
When you create a table in Corona/Lua you can put pretty much an unlimited number of things in it correct?
So say i create a table called
rectangles = {};
and then i put a bunch of instances of rectangles in it. If i wanted to change a property of ALL the rectangles at once, how could I do it?
I understand how it would work with a set number of items in the table, like:
for i = 1, 10 do
rectangles[i] = display.newImage("rectangle.png");
then to change all of the images x positions for instance you would simply say
rectangles[i].x = 20;
but how would you change a property of all items in the array without knowing how many there are, as in you didnt give an upper bound, and cant because the table is always growing?
For arrays that have only one kind of elements you can use #rectangles for element count.
for i = 1, #rectangles do
rectangles[i] = display.newImage("rectangle.png");
end
Regarding the youtube example,
if you add element into rectangles like this:
rectangles[b]=b;
what it actually does is
rectangles["083DF6B0"]=b"
you see when a display object b is used as a key it is converted into a hex string.
in addition, you would need to use pairs to go over each element as they are
keys (e.g. array.length,array.width,array.weight..) rather than index (e.g. array[2],array[3]..)
for key,value in pairs(rectangles) do
print(key); --prints 083DF6B0
print(value); --prints 20
rectangles[key]=30;
end
It depends on how you're storing items in the table. If you're storing by index (as in your example), you can use ipairs to iterate over indexes and values:
for index,value in ipairs(rectangles) do
value.x = 20
--or
rectangles[index].x = 20
end
If you're storing by key (as in the youtube video you mention in a comment), iterate using pairs:
for key,value in pairs(rectangles) do
value.x = 20
--or
rectangles[key].x = 20
end
Just don't store items using both index and keys, unless you know what to expect.

get first value in hash within hash

Is there a simple way, instead of looping my entire array to fetch the first value of every inner array.
so in essence I have the following;
array = [['test', 'test2'...], ['test' ....]]
so I want to grab array[#][0] and store the unqiue values.
EDIT
Is there a similar way to use the transpose method for arrays with Hash?
I essentially want to do the same thing
Hash = {1=> {1=> 'test', .....}, 2=> {1=> 'test',....}
so at the end I want to have something like new hash variable and leave my existing hash within hash alone.... = {1 => 'test', 2=> 'test2'}
Not sure if I fully understand the question, but if you have a 2 dimensional array (array in array), and you want to turn that into an array of the first element of the second dimension, you can use the map function
firsts = array.map {|array2| array2.first}
The way map works is that it turns one collection into a second collection by applying a function you provide (the block) to each element.
Maybe this?
array.transpose[0]

Resources