I need to know how to create object array in rails and how to add elements in to that.
I'm new to ruby on rails and this could be some sort of silly question but I can't find exact answer for that. So can please give some expert ideas about this
All you need is an array:
objArray = []
# or, if you want to be verbose
objArray = Array.new
To push, push or use <<:
objArray.push 17
>>> [17]
objArray << 4
>>> [17, 4]
You can use any object you like, it doesn't have to be of a particular type.
Since everything is an object in Ruby (including numbers and strings) any array you create is an object array that has no limits on the types of objects it can hold. There are no arrays of integers, or arrays of widgets in Ruby. Arrays are just arrays.
my_array = [24, :a_symbol, 'a string', Object.new, [1,2,3]]
As you can see, an array can contain anything, even another array.
Depending on the situation, I like this construct to initialize an array.
# Create a new array of 10 new objects
Array.new(10) { Object.new }
#=> [#<Object:0x007fd2709e9310>, #<Object:0x007fd2709e92e8>, #<Object:0x007fd2709e92c0>, #<Object:0x007fd2709e9298>, #<Object:0x007fd2709e9270>, #<Object:0x007fd2709e9248>, #<Object:0x007fd2709e9220>, #<Object:0x007fd2709e91f8>, #<Object:0x007fd2709e91d0>, #<Object:0x007fd2709e91a8>]
Also if you need to create array of words next construction could be used to avoid usage of quotes:
array = %w[first second third]
or
array = %w(first second third)
Related
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)
I have a script that creates an array , then adds items to the array depending on certain circumstances. In most cases, the array will end up with several values inside of it. Occasionally, the array will only hold one value inside of it.
After preparing this array, I usually call .join(",") to create a comma-separated string of all the array values:
tags.join(",")
It works fine when the array has multiple values, but when it only has one value it throws an error:
NoMethodError: undefined method 'join' for "Whatever the array value": String
Any idea why this is? What is the easiest way to resolve this? Do I need to do an if statement to check if the variable is an array or string? Seems a bit silly...let me know if I am missing something here.
If obj is your object, you can write
[*obj].join
For example
arr = ["Fa", "bu", "lo", "us!"]
[*arr].join #=> "Fabulous!"
str = "Whoa!"
[*str].join #=> "Whoa!"
This works because
[*arr] #=> ["Fa", "bu", "lo", "us!"] == arr
[*str] #=> ["Whoa!"]
Similarly,
[*[1,2,3]].join #=> "123"
[*7].join #=> "7"
You can use join on an array as following way :
#array = ["this","is","join","method","example"]
#array.join(" ")
"this is join method example"
#array.join("_")
"this_is_join_method_example"
In the case of a single element (say, 'Hello'), you should be calling join on an array, not the string itself; for example, ['Hello'].join(",") rather than 'Hello'.join(","). Of course, if there's only one element join doesn't actually do anything, so you could just use a conditional if to skip it... but that's kinda ugly. Most of the time, I'd use the construction Array(tags).join(","). If passed a single string, that'll wrap it in an array; if passed an array, it's a noop, returning the array as-is.
Lets say I have 2 arrays of users.
[user1, user2, user3]
[user3]
Based on the second array, I want to sort the first array so that occurrences in the second array appear first in the first array.
So the result of the first array would be:
[user3, user1, user2]
I realise the simple way would be to iterate over the first array and populate an empty array, ordering it if the second array contains it, then merging the rest. The below is pseudo code and untested, but gives an idea of what I was thinking as a simple solution
return_array = []
array1.each do |a|
if array2.include? a
return_array.push array1.pop(a)
end
end
return_array.merge array1
Is there any way to refine this? Built in rails or ruby methods for example.
You should use array intersection and array difference:
a&b + a-b
would give you what you're looking for.
The manual for intersection: http://ruby-doc.org/core-2.2.0/Array.html#method-i-26
The manual for difference: http://ruby-doc.org/core-2.2.0/Array.html#method-i-2D
You could just do this:
array2 + (array1 - array2)
my_array = ['user1', 'user2', 'user3']
my_array2 = ['user3']
my_array2 + (my_array.sort - my_array2)
Hi I have an array that i created using push like this
arr.push(h, s.power)
PS: h and s.power both are variables but depends on condition I applied
which ends up something like this
[22,"0.014",22,"0.01",22,"0.01",22,"0.082",22,"0.0002",22,"0.02822",22,"0.0042822",22,"0.041662",21,"0.0042822",21,"0.11107"]
but now I want to create new array for each new value like 22, 21 but I can not access it with many combinations I tried such as arr[22], with arr.map
You should consider using a Hash instead. See ruby hash documentation here.
So instead of pushing h and s.power into an array, you would add them to the hash like this:
my_hash[h] ||= []
my_hash[h].push(s.power)
The first line makes sure you have an array in the hash for the latest value of h. The second adds s.power to that array.
If you run this code repeatedly, you will end up with one array for each unique value of h which you can access like this:
my_hash[22] # <= returns the array of s.power values for h=22
my_hash[21] # <= returns the array of s.power values for h=21
If I understand your question correctly, this should be a clean way to do what you want.
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]