Why does the same lua script have inconsistent execution results?
hello.lua
obj = {
a = 'haha',
b = 'jiji',
c = {
name = 'tom',
age = 15
}
}
for i, v in pairs(obj) do
if (i == 'c') then
print(i,v.age,v.name)
break
end
print(i, v)
end
Result
Result
Thank you for your answer!!
The documentation is very clear, the order is not specified. See https://www.lua.org/manual/5.4/manual.html#pdf-next
The order in which the indices are enumerated is not specified, even for numeric indices. (To traverse a table in numerical order, use a numerical for.)
Lua tables use a hash map for implementing their hash part. The order in which your entries will be iterated by pairs/next depends on the hashes of the keys (in this case, the hashes of the strings "a", "b", "c") and their order of insertion.
First of all, hashing and order of insertion may change across different Lua versions, different interpreters (LuaJIT f.E.), so you should never rely on it being one way or another. You will probably want to either sort a list of table keys before traversal or to use an ordered map.
Second, hashing - and thus order of traversal - varies across program runs as of Lua 5.2, which introduces hash seeding to avoid hash flooding attacks: The interpreter will generate a random seed at runtime to use in the calculation of hashes to make it harder for attackers to force hash collisions (which result in detrimental table performance).
I was reading through the F# documentation and came across the compare function. The examples in the docs do not really make it clear what the function does. I also tried it with a few inputs, but couldn't find a clear pattern.
When comparing lists the values are either -1, 0 or 1.
> compare [1;2;4] [8;1;4;9]
-1
> compare [1;2;4] [1;2;3]
1
> compare [1;2;4] [1;2;4]
0
But when comparing strings the numbers can get larger than 1.
> compare "abf" "abc"
3
What does compare compare?
The F# Language specification provides a formal description of language elements. For the compare function see p. 173 "8.15.6 Behavior of Hash, =, and Compare", where the behavior is described in pseudocode to achieve the following objectives:
Ordinal comparison for strings
Structural comparison for arrays
Natural ordering for native integers (which do not support System.IComparable)
Structural comparison, an important concept in functional programming, does apply to tuples, lists, options, arrays, and user-defined record, union, and struct types whose constituent field types permit structural equality, hashing, and comparison.
For strings, the comparison relies on System.String.CompareOrdinal, whose return values are described under the System.String.Compare method:
Less than zero: strA precedes strB in the sort order.
Zero: strA occurs in the same position as strB in the sort order.
Greater than zero: strA follows strB in the sort order.
I know that pairs in lua iterates through pairs according to hash key, which means no specific order, and ipairs iterates from 1 until an absent key, which will not iterate through all pairs if there is a gap.
My question is, what is the i in ipairs stands for? I have a hard time thinking up a mnemonic explanation.
Some of my guesses are:
Incremental-key-order
In-order-iteration
Just because it behaves
like a for loop, which use i a lot
I'm playing around with iterators. What is Ruby comparing using max and min?
If I have this array:
word_array = ["hi", "bob", "how's", "it", "going"]
and I run:
puts word_array.max
puts word_array.min
I expect to get "going" or "how's" for max, since they're both five characters long, or "going" on the theory that it's the last item in the array. I expect min to return "hi" or "it", since they're tied for the shortest string. Instead, I get back:
puts word_array.max -> it
puts word_array.min -> bob
What is Ruby measuring to make this judgement? It selected the shortest string for max and a middle length string for min.
Actually, you are (kind of) asking the wrong question. max and min are defined on Enumerable. They don't know anything about Strings.
They use the <=> combined comparison operator (aka "spaceship"). (Note: pretty much any method that compares two objects will do so using the <=> operator. That's a general rule in Ruby that you can both rely on when using objects other people have written and that you should adhere to when writing your own objects: if your objects are going to be compared to one another, you should implement the <=> operator.)
So, the question you should be asking is, how does String#<=> compare Strings? Unfortunately, the answer is not quite clear from the documentation. However, it does mention that the shorter string is considered to be less than the longer string if the two strings are equal up to that point. So, it is clear that length is used only as a tie-breaker, not as the primary criterion (as you are assuming in your question).
And really, lexicographic ordering is just the most natural thing to do. If I gave you a list of words and asked you to order them without giving you any criteria, would you order them by length or alphabetically? (Note, however, that this means that '20' is less than '3'.)
I believe it's doing a lexical sort, exactly like a dictionary order. The maximum would be the furthest one in the dictionary.
http://ruby-doc.org/core-2.1.0/Enumerable.html#method-i-max_by
ar = ['one','two','three','four','five']
ar.max_by(&:length) # => "three"
I want to construct a string in Java that represents a DICT term and that will be passed to an Erlang process for being reflected back as an erlang term ( string-to-term ).
I can achieve this easily for ORDDICT 's, since they are structured as a simple sorted key / value pair in a list of tuples such as : [ {field1 , "value1"} , {field2 , "value2} ]
But, for DICTS, they are compiled into a specific term that I want to find how to reverse-engineer it. I am aware this structure can change over new releases, but the benefits for performance and ease of integration to Java would overcome this. Unfortunately Erlang's JInterface is based on simple data structures. An efficient DICT type would be of great use.
A simple dict gets defined as follows:
D1 = dict:store("field1","AAA",dict:new()).
{dict,1,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
{{[],[],[],[],[],[],[],[],
[["field1",65,65,65]],
[],[],[],[],[],[],[]}}}
As it can be seen above, there are some coordinates which I do not understand what they mean ( the numbers 1,16,16,8,80,48 and a set of empty lists, which likely represent something as well.
Adding two other rows (key-value pairs) causes the data to look like:
D3 = dict:store("field3","CCC",D2).
{dict,3,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
{{[],[],
[["field3",67,67,67]],
[],[],[],[],[],
[["field1",65,65,65]],
[],[],[],[],
[["field2",66,66,66]],
[],[]}}}
From the above I can notice that:
the first number (3) reppresets the number of items in the DICT.
the second number (16) shows the number of list slots in the first tuple of lists
the third number (16) shows the number of list slots in the second typle of lists, of which the values ended up being placed on ( in the middle ).
the fourth number (8) appears to be the number of slots in the second row of tuples from where the values are placed ( a sort of index-pointer )
the remaining numbers (80 and 48)... no idea...
adding a key "field0" gets placed not in the end but just after "field1"'s data. This indicates the indexing approach.
So the question, is there a way (algorithm) to reliably directly create a DICT string from outside of Erlang ?
The comprehensive specification how dict is implemented can be found simply in the dict.erl sourcecode.
But I'm not sure replicating dict.erl's implementation in Java is worthwhile. This would only make sense if you want a fast dict like data structure that you need to pass often between Java and Erlang code. It might make more sense to use a Key-Value store both from Erlang and Java without passing it directly around. Depending on your application this could be e.g. riak or maybe even connect your different language worlds with RabbitMQ. Both examples are implemented in Erlang and are easily accessible from both worlds.