Inverse mapping in dart - dart

Say that I have the following map in dart:
Map f = {
0 : 0,
1 : 1,
2 : 0,
3 : 1,
4 : 0,
5 : 1
};
Is there something in dart so that you can easily work with the inverse map of the map f? So for example, the inverse map f⁻¹[0] (in math notation) should be equal to the set 0, 2, 4 in this case.

If values are unique then it's just:
Map inverse(Map f) {
return f.map( (k, v) => MapEntry(v, k) );
}
it doesn't complain about duplicates, it overwrites them.

Map f = {
0 : 0,
1 : 1,
2 : 0,
3 : 1,
4 : 0,
5 : 1
};
main() {
print(f.keys.where((k) => f[k] == 0));
// or
print(new Map.fromIterable(f.values.toSet(),
key: (k) => k,
value: (v) => f.keys.where((k) => f[k] == v)));
}
try at DartPad

There's also the BiMap class in quiver.dart library (although it might be overkill to use a library for just this single purpose).
Here is an example real-world usage of this class.

Inspired by gunter's answer:
Map inverse(Map f) {
Map inverse = {};
f.values.toSet().forEach((y) {
inverse[y] = f.keys.where((x) => f[x] == y).toSet();
});
return inverse;
}
DartPad demo

Related

I don't Understand "How Lua save data on the same variable when we Iterate over it"

I know Lua remember value in the same field/function with the Same defined Variable. but I still lack the concept behind it. Let's say I'see Int Variable = 2 which can be modify if we iterate over it Int variable = 8
Same logic I was applying on the Code. I got the results, but I didn't understand the concept behind it.
You Can see in my Code I was saving some value in Var x and saveX
and I was doing saveX = x from my logic The value of x should be saved inside saveX instead it was saving the loop value as I'm applying over it. Why is that?
-- Graphical Representation of table1
--[[ { { {},{},{},{} },
{ {},{},{},{} },
{ {},{},{},{} },
{ {},{},{},{} } } ]]
_Gtable1 = {}
for y = 1, 4 do
table.insert(_Gtable1, {})
for x = 1, 4 do
table.insert(_Gtable1[y], {
x = (x - 1) * 10, --Coordinate value of X
y = (y - 1) * 10, --Coordinate value of Y
-- what if i want to save Coordinate value on another variable How should i do?
saveX = x, -- Saving Loop X
saveY = y, -- Saving Loo Y
t = "Check" -- to Debug
})
end
end
ti = _Gtable1
for y = 1, 4 do
for x = 1, 4 do
tim = ti[y][x]
-- print(tim.saveX) -- output 1, 2, 3, 4
print(tim.x) -- output 0, 10, 20, 30
end
end
I hope I understood the question:
Let's simplify the example:
local t = {
x = 10,
y = x,
}
You assume t.y is 10, because you declared it a line before that? But it is nil here, because x = 10, is no variable. It's part of the table constructor and can not be referenced in the same constructor. Check out https://www.lua.org/pil/3.6.html for more details.
After the constructor has finished, you can access that as t.x (not x!).
Now for your example, you need to move (x - 1) * 10 outside the constructor, e.g.: local tempX = (x - 1) * 10. Then use tempX inside the constructor. Or you can set your values individually, e.g. _Gtable1[y][x].saveX = _Gtable1[y][x].x. I would prefer the former.

Inserting words into a table

So, i have a script where i am inputting 3 words in a string and putting them into a small table and i only need this script to print a new table i can copy and paste, so i just need to print what the table would look like this is the script currently have
local tbl = {
{1, "", 0},
{2, "", 0},
{3, "", 0}
}
local input = "i hate debugging"
local words = {}
x = 0
repeat
x = x + 1
for i, v in ipairs(tbl) do
if tonumber(v[1]) == x then
for word in input:gmatch"[^ ,\r\n]+" do
table.insert(words, word)
end
end
end
until x == 1
and the desired output should look like this
{1, "i", 0},
{2, "hate", 0},
{3, "debugging", 0},
The question isn't very clear, and OP goal is not clear, but it seems that you may want something like this:
local tbl = {
{ 1, "", 0 },
{ 2, "", 0 },
{ 3, "", 0 }
}
local input = "i hate debugging"
local nextWord = input:gmatch"[^ ,\r\n]+"
for k, t in ipairs(tbl) do
t[2] = nextWord() or ""
end
-- Display updated `tbl`
print("updated tbl")
for k, v in ipairs(tbl) do
print(string.format('{ %d, "%s", %d },', v[1], v[2], v[3]))
end
gmatch returns an iterator, so you can just call this iterator repeatedly to get successive matches. You can loop over tbl, calling the iterator each time to set the string. When the iterator is out of matches it will return nil, so the code sets the string to "" when the iterator is exhausted.
Program output:
updated tbl
{ 1, "i", 0 },
{ 2, "hate", 0 },
{ 3, "debugging", 0 },
Creating A New Table From Input
OP has clarified in a comment that a new table should be created from the input. Here is a function createWordTable that creates and returns a fresh table from a string of words. The printWordTable function is just a utility function to show the contents of a word table.
function createWordTable(wordString)
local wordTbl = {}
local i = 1
for w in wordString:gmatch"[^ ,\r\n]+" do
wordTbl[i] = { i, w, 0 }
i = i + 1
end
return wordTbl
end
function printWordTable(wordTbl)
for k, v in ipairs(wordTbl) do
print(string.format('{ %d, %s, %d }', v[1], v[2], v[3]))
end
end
Sample interaction:
> wtbl = createWordTable("one, two, three")
> printWordTable(wtbl)
{ 1, one, 0 }
{ 2, two, 0 }
{ 3, three, 0 }
> wtbl = createWordTable("one, two, three, four, five")
> printWordTable(wtbl)
{ 1, one, 0 }
{ 2, two, 0 }
{ 3, three, 0 }
{ 4, four, 0 }
{ 5, five, 0 }

Add all elements from a table to another table in lua

In javascript you can do the following
const obj1 = {a:1, b:'blue', c:true};
const obj2 = {...obj1, d:3, e:'something else'};
and you object 2 will have all of obj 1 in it.
Is there a way to do this in lua?
You'd have to write your own function for this purpose:
local function add_missing(dst, src)
for k, v in pairs(src) do
if dst[k] == nil then
dst[k] = v
end
end
return dst -- for convenience (chaining)
end
which you may then use as follows:
local obj1 <const> = {a = 1, b = 'blue', c = true}
local obj2 <const> = add_missing({d = 3, e = 'something else'}, {a = 1, b = 'blue', c = true})
Note: JavaScript's spread operator also guarantees a certain order of execution; that is, in your example fields from obj2 would override those from obj1, which is why I've included an explicit nil check to only include missing fields:
> {...{a: 2}, a: 1}
{ a: 1 }
> {a: 1, ...{a: 2}}
{ a: 2 }

How do you efficiently apply a numeric operation to an array in lua?

Say, I have an array
a = { 1, 2, 10, 15 }
I would like to divide each element by 3 and store the result in a new array. Is there a more efficient / elegant way of doing that than this:
b = { }
for i,x in pairs(a) do
b[i] = x / 3
end
In R, I would simply do b <- a/3. Is there anything like that in lua, or maybe a way of applying a function to each element of a table?
Lua is lightweight, so there is no ready-made functions, but you can create a similar function with metatable.
local mt_vectorization = {
__div = function (dividend, divisor)
local b = {}
for i,x in pairs(dividend) do
b[i] = x / divisor
end
return b
end
}
a = setmetatable({ 1, 2, 10, 15 }, mt_vectorization)
b = a / 3
In addition to the answer by shingo, I found in the meanwhile that writing an R-style mapping function is very easy in lua:
function map(x, f)
local ret = { }
for k, v in pairs(x) do
ret[k] = f(v)
end
return ret
end
This makes some operations easy, for example
a = { 1, 2, 3, 5, 10 }
map(a, function(x) return x * 2 end)

Dart - Are sets really unordered?

From the documentation:
A set in Dart is an unordered collection of unique items.
But if I run this sample code:
final a = {0, 1, 2};
final b = {2, 1, 0};
for (final i in a) {
print('a - $i');
}
for (final i in b) {
print('b - $i');
}
print(a == b);
I get the output
a - 0
a - 1
a - 2
b - 2
b - 1
b - 0
false
The 2 iterables a and b don't behave the same when looped over and == is false (But I guess == makes sense since the a and b are not the same instance).
However, what I don't understand is if a and b are constants:
const a = {0, 1, 2};
const b = {2, 1, 0};
for (final i in a) {
print('a - $i');
}
for (final i in b) {
print('b - $i');
}
print(a == b);
This yields the same output.
And if I order b as a:
const a = {0, 1, 2};
const b = {0, 1, 2};
for (final i in a) {
print('a - $i');
}
for (final i in b) {
print('b - $i');
}
print(a == b);
It logs:
a - 0
a - 1
a - 2
b - 0
b - 1
b - 2
true
I'm a bit surprised that const a = {0, 1, 2} and const b = {2, 1, 0} are not equal. Aren't const variable being reused, and aren't a and b supposed to be equal since sets are unordered?
What am I missing?
Dart sets are ordered in the sense that if you use their iterator, you get elements in some order. That order may or may not be predictable. The order is unspecified for sets in general, but some Set implementations may choose to specify a specific ordering.
The one thing that is required is that the ordering of a set doesn't change unless the set changes. So, if you iterate the same set twice, without changing it in-between, you get the same ordering — whatever it is.
LinkedHashSet promises insertion ordering.
SplayTreeSet promises comparator ordering.
Constant set literals promise source ordering (first occurrence if the same value occurs more than once). They're like immutable LinkedHashSets.

Resources