I am trying to sort the "fields" in a hash.
For example,
mykey, cde, firstone
mykey, abcde, secondone
mykey, bcde, thirdone
I want to sort the fields(cde, abcde, bcde) in alphabet order, but there is no way to do so.. If anyone knows about this, please help me.
If there is no way to solve this, I am thinking about changing names of key&values.. and use zadd instead of hash. If you have a better solution, please give me an advice here.
Hash field names are not sortable-by easily - there is no native command to do so and the order in which fields are returned (e.g. with HGETALL) is for all intents and purposes random.
While Sorted Sets are preferable when it comes to sorting, you could work around this with use of a Lua script that will perform lexical sorting the Hash's fields. For example:
$ cat hashsort.lua
local r = redis.call('HGETALL',KEYS[1])
local t = {}
for i=1,#r,2 do
t[#t+1] = { field = r[i], value = r[i+1] }
end
table.sort(t, function(a,b) return a.field < b.field end)
r = {}
for _, v in pairs(t) do
r[#r+1] = v.field
r[#r+1] = v.value
end
return r
$ redis-cli HMSET hash z 99 ee 55 e 5 a 1 b 2 ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ justsomethinglongsohashmaxzipwillbeexceeded
OK
$ redis-cli --eval hashsort.lua hash
1) "a"
2) "1"
3) "b"
4) "2"
5) "e"
6) "5"
7) "ee"
8) "55"
9) "z"
10) "99"
11) "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
12) "justsomethinglongsohashmaxzipwillbeexceeded"
There is a name list without any order.
How to sort name list by alphabet order?
What I mean is how to compare two strings to find out greater one?
Is there any existing method or function to do this like Java does?
In Java, we can use
"abc".compareTo("abb");
to compare strings greater or smaller.
Yes. You can use sort function of array like below,
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
var reversed = names.sort({s1,s2 in s1 < s2})
//var reversed = names.sort {$0 < $1} // Shorter version of Closure.
print(reversed)
I have two arrays and I want to see the total number of matches, between the arrays individual items that their are.
For example arrays with:
1 -- House, Dog, Cat, Car
2 -- Cat, Book, Box, Car
Would return 2.
Any ideas? Thanks!
EDIT/
Basically I have two forms (for two different types of users) that uses nested attributes to store the number of skills they have. I can print out the skills via
current_user.skills.each do |skill| skill.name
other_user.skills.each do |skill| skill.name
When I print out the array, I get: #<Skill:0x1037e4948>#<Skill:0x1037e2800>#<Skill:0x1037e21e8>#<Skill:0x1037e1090>#<Skill:0x1037e0848>
So, yes, I want to compare the two users skills and return the number that match. Thanks for your help.
This works:
a = %w{house dog cat car}
b = %w{cat book box car}
(a & b).size
Documentation: http://www.ruby-doc.org/core/classes/Array.html#M000274
To convert classes to an array using the name, try something like:
class X
def name
"name"
end
end
a = [X.new]
b = [X.new]
(a.map{|x| x.name} & b.map{|x| x.name}).size
In your example, a is current_user.skills and b is other_users.skills. x is simply a reference to the current index of the array as the map action loops through the array. The action is documented in the link I provided.
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 problem I can't for the life of me solve. I'm writing a Ruby app (I've been a PHP developer for 8 years, just starting with Ruby) that sells tickets for a concert hall. Each seat has a row (a...z) and a number (1...x). The database model has row (string) and num (int) for each seat.
How can I convert my array of seats from the database into a 2d array? For example, seat A1 would go into seat[1][1] = "value"; seat C4 would map to seat[3][4] = value. The issue is converting the row string to Ascii and subtracting the offset? Or is there an easier way?
Many thanks
The simplest way is probably to use a hash instead. For example: seat['A'][1] = value
But if you really need an array for some reason, then the method you describe is the simplest. Assuming the row string is a single character 'A' through 'Z', you can do it using row_string[0] - ?A (or row_string[0] - ?A + 1 if you want the index starting at 1 as in your example). For a multi-character version where row AA is after row Z, you can do this in 1.8.7 and newer:
row_num = row_string.bytes.inject(0) {|total, x| total = total * 26 + x - ?A + 1}
You may want to upcase your row string beforehand, just to be on the safe side.
In 1.8.6 and below, String does not have a bytes method. You can accomplish the same thing by doing:
row_num = 0
row_string.each_byte {|x| row_num = row_num * 26 + x - ?A + 1}
Ok, the solution I've come up with that seems to do the trick:
seat_array = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) }
for seat in self.seats
seat_array[seat.row.downcase][seat.num] = seat
end
return seat_array
Many thanks to everyone for such quick and useful responses. I'll certainly be helping others with PHP!
Well to get the index of a letter you could do something like this
('A'..'Z').to_a.index('C')
which would return 2
I notice in the array examples you gave you started A = 1 instead of 0.