I use:
b.x = {}
a = Obj()
a:AddParams("a", "b", "c")
...
...
function Obj:AddParams(a, b, c, d, e)
table.insert(b.x, {["one"] = a, ["two"] = b, ["three"] = c, ["four"] = d, ["five"] = e})
end
and then I print #b.x and it prints 1. Shouldn't it print 2 since # operator counts nil values and I only give the first 3 parametrers on a:AddParams, leaving the last two nil? Thanks a lot
Shouldn't it print 2 since # operator counts nil values
No, exactly the opposite!
First of all, the whole notion of adding a nil to a table is invalid. You can store anything in a table except nil. Doing so simple deletes the value already present in that key (index) but doesn't insert a nil inside. It's like the mathematical null set ∅ which is used to denote emptiness as an entity but is not a tangible value/object. Accessing any index not present in the table would give you nil, you don't have to insert one to see them being there; any non-existent key has the value nil denoting that the value isn't there.
> a = { }
> print(a[1])
nil
> a = { "abc" }
> print(a[1])
abc
> a[1] = nil -- this is just erasing 'abc' from the table; not add/insert nil
> print(a[1])
> nil
Thus they never constitute towards the size of the table.
The length operator returns, n, the count of the elements in a sequence; a sequence is a table with values (non-nil of course - which is implied since one can never insert a nil as noted above) indexed by contiguous integers starting from 1 extending to some positive integer n. If they aren't continuous (broken with holes) then the operator # shouldn't be used. The Lua manual specifically calls out that using # is defined only if a table is a sequence. However, note that non-integer keys have no bearing on the sequence nature of the table.
Now that you've clarified what your code is doing:
b.x actually winds up being a one element table for which the single element is another table due to how your code calls table.insert:
b.x = {
[1] = { <======= this single element in the top-level
["one"] = "a", b.x table is what the # operator counts
["two"] = "b", when you apply it as #b.x
["three"] = "c"
}
}
Thus, calling #b.x will always return 1 no matter what you pass to your function, because you're always adding that table as a single element in the originally empty table you initialize b.x to be.
Note however that even if you didn't create this nested table, the value returned from # still wouldn't be what you're expecting. The # operator does not count nil values. What the # operator counts is the length of the sequential numerical indices of a table starting at 1 (and is not defined for tables with non-sequential numerical indices). Thus,
#{ [1]="a", [2]="a" } evaluates to 2
#{ [1]="a", [3]="a" } is not defined by the Lua standard, because of non-sequential indices
#{ [1]="a", ["two"]="b" } evaluates to 1 (because "two" isn't a number, it's a string).
Previous answer...
Not sure where you're getting 1 from:
> a = {}
> a[1] = "a"
> a[2] = "b"
> a[3] = "c"
> a[4] = nil
> a[5] = nil
> print(#a)
3
(Note that assigning nil as a value at the end of a table does nothing - you'd get the same result omitting the a[4] and a[5] lines.)
Did you perhaps actually skip a[2]? That would result in #a being 1, since it only counts contiguous items starting from index 1.
You are constructing a table and inserting it into an empty table with key 1. If you want to insert multiple elements, you have to call insert for each one.
And, the table you are constructing has string keys, which don't influence # at all.
I suggest you use an IDE with a debugger. See that [lua] tag wiki.
Related
How does it work and why does the loop return values for k, v vars in order?
Why if I just call the next() function many times it does not return the same result as in the loop?
Where does the for loop get the values for the second argument of the next() function?
I don't understand how it works
local t = {'a', 'b', 'c'}
-- prints 1 a, 2 b, 3 c
for k, v in next, t, nil do
print(k, v)
end
print()
print(next(t)) -- 1 a
print(next(t)) -- why not 2 b?
print(next(t)) -- why not 3 c?
I don't understand much there https://www.lua.org/pil/7.html, I asked a question. How it works in lua - iterators, for loops, closures
next is a stateless iterator. That is, next is a pure function - its return values are determined only by its inputs (the invariant state: the table & the loop control variable: the key)
This explains why
print(next(t)) -- 1 a
print(next(t)) -- why not 2 b?
print(next(t)) -- why not 3 c?
must print 1 a three times: Each time, you call next with the table as first (and nothing as second argument). If the second argument to next is nil or nothing, next returns the first key-value pair of the given table. To get the next k-v-pair, you need to pass that key to next: next(t, 1) may give you 2 b. To fix your subsequent calls to next, you need to always pass the last key to get the next k-v-pair:
local k, v = next(t)
print(k, v) -- 1st entry
k, v = next(t, k)
print(next(t, k)) -- 2nd entry
k, v = next(t, k)
print(next(t, k)) -- 3rd entry
note that it is not guaranteed that next traverses the list part of a table in order (although all implementations do it this way)
As outlined in the PIL chapter 7.2, a for-loop is just syntactic sugar to iterate over such an iterator (for the sake of simplicity, we assume every iterator returns two values like next):
for k, v in next, t, nil do
print(k, v)
end
is equivalent to
local iterator_func, invariant_state, control_var = next, t, nil
while true do
local k, v = iterator_func(invariant_state, control_var)
if k == nil then break end
print(k, v)
control_var = k
end
pairs(t) is just even more sugar for next, t, nil (which may also be written as next, t). You can trivially implement pairs yourself as function pairs() return next, t, nil end. ipairs works similarly, except it doesn't use next but an "inext" iterator which only considers integer keys (and guarantees inorder traversal).
Stateful iterators on the other hand usually have a hidden state (usually upvalues of a closure). Every call to the iterator function changes the hidden state; the invariant state and loop control variable usually is not needed at all (and ignored entirely). These iterators behave as you would expect. We can write a stateful pairs (that is, a pairs which always returns a closure remembering the current position of the "cursor" in the table) as follows by making the current key an upvalue:
function stateful_pairs(t)
local key
-- This is the iterator function: Note how we may take no params
-- since we have everything as an upvalue already
return function()
local value
key, value = next(t, key)
return key, value
end
end
this now works the way you expected in your example, because the closure returned by this pairs remembers its state in upvalues:
local stateful_next = stateful_pairs(t)
print(stateful_next(t)) -- 1 a
print(stateful_next(t)) -- 2 b
print(stateful_next(t)) -- 3 c
and you can still use this in a for-loop. For stateful iterators without parameters, a for loop is just syntactic sugar for calling a function until it returns nil:
for k, v in stateful_pairs(t) do
print(k, v)
end
Lua has a few stateful iterators such as io.lines or string.gmatch in its standard library; making them stateless would require a very ugly loop control variable & invariant state.
I am new to constraint programming and to Minizinc.
I have look for a solution to this not relly hard task but I found nothing.
I want to count the number of different elements that appear in an array:
This is the declaration of my array:
array[1..n,1..n] of var 1..n: countLeft;
I have try to do like this:
constraint
forall(j in 1..n) (
length(array2set([countLeft[i,j]|i in 1..stopCountLeft[j]]) )==left_vision[j]
);
But apparently my array is of type: array[int]of var opt int and is not accept by the function array2set.
Any ideas?
There might be different approaches you could take, but an approach that is similar to what you try would be to split the counting of different elements in an array into two steps:
Counting the occurrence of the values in the domain.
Counting the amount of times the occurrence is higher than zero.
We can use the global global_cardinality constraint to count the occurrences and then use a simply count constraint over its result.
include "global_cardinality_fn";
array[1..n] of var int: occurrences = global_cardinality(YOURARRAY, [i | i in 1..n]);
var int: num_diff = count(o in occurrences) (o > 0);
Note, however, that this might not be the best code for your model. For some solvers global_cardinality might not be perform well enough. Similarly if your stopCountLeft contains variables, then that means that you are creating a array of optional variables, and global_cardinality might not be defined for optional variables.
Instead we can write an implication graph instead. The idea is still the same, but instead of counting the number of a value occurring, we just use a boolean value to signal wether the value is in use.
array[1..n] of var bool: occurs;
constraint forall(i,j in 1..n) (YOURARRAY[i] = j -> occurs[j]);
var int: num_diff = count(occurs);
Note that the problem with this approach is the exponential number of implications posted in the forall loop. However, I suspect that, with implications being small, it would perform reasonably well.
In MiniZinc 2.5.0, you can do something like this:
array[int, int] of int: a =
[| 1, 1,
| 2, 3,
| 3, 4 |];
set of int: Rows = index_set_1of2(a);
set of int: Cols = index_set_2of2(a);
int: values = card({ a[r, c] | r in Rows, c in Cols });
output ["\(values) values in "] ++
[if c == 1 then "\n" else "" endif ++
"\(a[r, c]) " | r in Rows, c in Cols];
Does PostgreSQL have some way for me to find if an array is contained within another array, but with the same ordering?
For example, I want to know if array1 is within array2 with matching elements in the same order.
array1[1, 3, 6, 8]
array2[3, 8, 2, 9, 10, 1, 6]
Obviously not the case in the example, but is there a built-in method for this in PostgreSQL or should I create my own function?
Version of PostgreSQL is 9.6. The actual numbers the query will run on are bigints.
General case
All elements of the second array are in the first, too. In the same order, but gaps are allowed.
I suggest this polymorphic PL/pgSQL function:
CREATE OR REPLACE FUNCTION array_contains_array_in_order(arr1 ANYARRAY
, arr2 ANYARRAY
, elem ANYELEMENT = NULL)
RETURNS bool AS
$func$
DECLARE
pos int := 1;
BEGIN
FOREACH elem in ARRAY arr2
LOOP
pos := pos + array_position(arr1[pos:], elem); -- see below
IF pos IS NULL THEN
RETURN FALSE;
END IF;
END LOOP;
RETURN true; -- all elements found in order
END
$func$ LANGUAGE plpgsql IMMUTABLE COST 3000;
As #a_horse commented, we can omit the upper bound in array subscripts to mean "unbounded" (arr1[pos:]). In older versions before 9.6 substitute with arr1[pos:2147483647] - 2147483647 = 2^31 - 1 being the theoretical max array index, the greatest signed int4 number.
This works for ...
any 1-dimensional array type, not just integer[].
arrays with NULL values, thanks to array_position() which works for NULL, too.
arrays with duplicate elements.
only for default array subscripts starting with 1. You can easily cover non-standard subscripts if needed:
Normalize array subscripts for 1-dimensional array so they start with 1
About the ANYELEMENT trick:
How do I get the type of an array's elements?
Performance
I ran a quick performance test comparing this function to the one #a_horse supplied. This one was around 5x faster.
If you use this a filter for a big table I strongly suggest you combine it with a (logically redundant) sargable filter like:
SELECT *
FROM tbl
WHERE arr #> '{2,160,134,58,149,111}'::int[]
AND array_contains_array_in_order(arr, '{2,160,134,58,149,111}')
This will use a GIN index on the array column like:
CREATE INDEX ON tbl USING gin (arr);
And only filter remaining (typically very few!) arrays that share all elements. Typically much faster.
Caveats with intarray module
Note: applies to integer[] exclusively, not smallint[] or bigint[] or any other array type!
Careful, if you have installed the intarray extension, which provides its own variant of the #> operator for int[]. Either you create an (additional) GIN index with its special operator class (which is a bit faster where applicable):
CREATE INDEX ON intarr USING gin (arr gin__int_ops);
Or, while you only have a GIN index with the default operator class, you must explicitly denote the standard operator to cooperate with the index:
WHERE arr OPERATOR(pg_catalog.#>) '{2,160,134,58,149,111}'::int[]
Details:
GIN index on smallint[] column not used or error "operator is not unique"
Simple case
As commented, your case is simpler:
The complete second array is included in the first (same order, no gaps!).
CREATE OR REPLACE FUNCTION array_contains_array_exactly(arr1 ANYARRAY, arr2 ANYARRAY)
RETURNS bool AS
$func$
DECLARE
len int := array_length(arr2, 1) - 1; -- length of arr2 - 1 to fix off-by-1
pos int; -- for current search postition in arr1
BEGIN
/* -- OPTIONAL, if invalid input possible
CASE array_length(arr1, 1) > len -- array_length(arr2, 1) - 1
WHEN TRUE THEN -- valid arrays
-- do nothing, proceed
WHEN FALSE THEN -- arr1 shorter than arr2
RETURN FALSE; -- or raise exception?
ELSE -- at least one array empty or NULL
RETURN NULL;
END CASE;
*/
pos := array_position(arr1, arr2[1]); -- pos of arr2's 1st elem in arr1
WHILE pos IS NOT NULL
LOOP
IF arr1[pos:pos+len] = arr2 THEN -- array slice matches arr2 *exactly*
RETURN TRUE; -- arr2 is part of arr1
END IF;
pos := pos + array_position(arr1[(pos+1):], arr2[1]);
END LOOP;
RETURN FALSE;
END
$func$ LANGUAGE plpgsql IMMUTABLE COST 1000;
Considerably faster than the above for longer arrays. All other considerations still apply.
I want to compare the pixel values of two images, which I have stored in arrays.
Suppose the arrays are A and B. I want to compare the elements one by one, and if A[l] == B[k], then I want to store the match as a key value-pair in a third array, C, like so: C[l] = k.
Since the arrays are naturally quite large, the solution needs to finish within a reasonable amount of time (minutes) on a Core 2 Duo system.
This seems to work in under a second for 1024*720 matrices:
A = randi(255,737280,1);
B = randi(255,737280,1);
C = zeros(size(A));
[b_vals, b_inds] = unique(B,'first');
for l = 1:numel(b_vals)
C(A == b_vals(l)) = b_inds(l);
end
First we find the unique values of B and the indices of the first occurrences of these values.
[b_vals, b_inds] = unique(B,'first');
We know that there can be no more than 256 unique values in a uint8 array, so we've reduced our loop from 1024*720 iterations to just 256 iterations.
We also know that for each occurrence of a particular value, say 209, in A, those locations in C will all have the same value: the location of the first occurrence of 209 in B, so we can set all of them at once. First we get locations of all of the occurrences of b_vals(l) in A:
A == b_vals(l)
then use that mask as a logical index into C.
C(A == b_vals(l))
All of these values will be equal to the corresponding index in B:
C(A == b_vals(l)) = b_inds(l);
Here is the updated code to consider all of the indices of a value in B (or at least as many as are necessary). If there are more occurrences of a value in A than in B, the indices wrap.
A = randi(255,737280,1);
B = randi(255,737280,1);
C = zeros(size(A));
b_vals = unique(B);
for l = 1:numel(b_vals)
b_inds = find(B==b_vals(l)); %// find the indices of each unique value in B
a_inds = find(A==b_vals(l)); %// find the indices of each unique value in A
%// in case the length of a_inds is greater than the length of b_inds
%// duplicate b_inds until it is larger (or equal)
b_inds = repmat(b_inds,[ceil(numel(a_inds)/numel(b_inds)),1]);
%// truncate b_inds to be the same length as a_inds (if necessary) and
%// put b_inds into the proper places in C
C(a_inds) = b_inds(1:numel(a_inds));
end
I haven't fully tested this code, but from my small samples it seems to work properly and on the full-size case, it only takes about twice as long as the previous code, or less than 2 seconds on my machine.
So, if I understand your question correctly, you want for each value of l=1:length(A) the (first) index k into B so that A(l) == B(k). Then:
C = arrayfun(#(val) find(B==val, 1, 'first'), A)
could give you your solution, as long as you're sure that every element will have a match. The above solution would fail otherwise, complaning that the function returned a non-scalar (because find would return [] if no match is found). You have two options:
Using a cell array to store the result instead of a numeric array. You would need to call arrayfun with 'UniformOutput', false at the end. Then, the values of A without matches in B would be those for which isempty(C{i}) is true.
Providing a default value for an index into A with no matches in B (e.g. 0 or NaN). I'm not sure about this one, but I think that you would need to add 'ErrorHandler', #(~,~) NaN to the arrayfun call. The error handler is a function that gets called when the function passed to arrayfun fails, and may either rethrow the error or compute a substitute value. Thus the #(~,~) NaN. I am not sure that it would work, however, since in this case the error is in arrayfun and not in the passed function, but you can try it.
If you have the images in arrays A & B
idx = A == B;
C = zeros(size(A));
C(idx) = A(idx);
I've embedded Lua into my C application, and am trying to figure out why a table created in my C code via:
lua_createtable(L, 0, numObjects);
and returned to Lua, will produce a result of zero when I call the following:
print("Num entries", table.getn(data))
(Where "data" is the table created by lua_createtable above)
There's clearly data in the table, as I can walk over each entry (string : userdata) pair via:
for key, val in pairs(data) do
...
end
But why does table.getn(data) return zero? Do I need to insert something into the meta of the table when I create it with lua_createtable? I've been looking at examples of lua_createtable use, and I haven't seen this done anywhere....
table.getn (which you shouldn't be using in Lua 5.1+. Use the length operator #) returns the number of elements in the array part of the table.
The array part is every key that starts with the number 1 and increases up until the first value that is nil (not present). If all of your keys are strings, then the size of the array part of your table is 0.
Although it's a costly (O(n) vs O(1) for simple lists), you can also add a method to count the elements of your map :
>> function table.map_length(t)
local c = 0
for k,v in pairs(t) do
c = c+1
end
return c
end
>> a = {spam="data1",egg='data2'}
>> table.map_length(a)
2
If you have such requirements, and if your environment allows you to do so think about using penlight that provides that kind of features and much more.
the # operator (and table.getn) effectivly return the size of the array section (though when you have a holey table the semantics are more complex)
It does not count anything in the hash part of the table (eg, string keys)
for k,v in pairs(tbl) do count = count + 1 end