How do Hamcrest's hasItems, contains and containsInAnyOrder differ? - hamcrest

Hamcrest provides a number of matchers for asserting the contents of a collection. All of these cases pass:
Collection<String> c = ImmutableList.of("one", "two", "three");
assertThat(c, hasItems("one", "two", "three");
assertThat(c, contains("one", "two", "three");
assertThat(c, containsInAnyOrder("one", "two", "three");
How do hasItems, contains and containsInAnyOrder differ?

hasItems checks:
consecutive passes over the examined Iterable yield at least one item that is equal to the corresponding item from the specified items.
That is, it makes sure that the collections contains at least these items, in any order. So,
assertThat(c, hasItems("one", "two"));
would also pass, with the extra item being ignored. And:
assertThat(c, hasItems("three", "two", "one"));
would also pass.
contains checks:
a single pass over the examined Iterable yields a series of items, each logically equal to the corresponding item in the specified items. For a positive match, the examined iterable must be of the same length as the number of specified items.
So it makes sure that the collection contains exactly these items:
assertThat(c, contains("one", "two")); // Fails
This would fail, as the leftover "three" is not matched.
assertThat(c, contains("three", "two", "one")); // Fails
This fails because the corresponding items don't match.
Another related matcher, containsInAnyOrder, checks that exactly those items are present, but in any order:
Creates an order agnostic matcher for Iterables that matches when a single pass over the examined Iterable yields a series of items, each logically equal to one item anywhere in the specified items.
A test with a missing item fails:
assertThat(c, containsInAnyOrder("one", "two")); // Fails
But all items in a different order will pass:
assertThat(c, containsInAnyOrder("three", "two", "one"));

Related

Dart, compare two lists and return element from first list that does not exist in second list

I have two lists,
List first = [{'name':'ABC','serialNumber':'ABC-124-353'},
{'name':'XYZ','serialNumber':'XYZ-123-567'},
{'name':'GRE', 'serialNumber': 'GRE-290-128'}];
List second = [{'name':'PQR','serialNumber':'PQR-D123-SII23'},{'name':'GAR','serialNumber':'GAR-G43-432'},
{'name':'MNOP','serialNumber':'XYZ-123-567'}];
Is there any easier way to compare first list and second list by serialNumber.
such that element from first list that doesn't exist in second list are outputted as a result.
So in this case
[{'name':'ABC','serialNumber':'ABC-124-353'},{'name':'GRE', 'serialNumber': 'GRE-290-128'}]
from first list is desired output, because ABC-124-353 and GRE-290-128 doesn't exist in list second
Another solution would be to use where on your first List to check if the serialNumber is contained in the second list:
final secondSerials = second.map((item) => item['serialNumber']).toSet();
print(first.where((item) => !secondSerials.contains(item['serialNumber'])).toList());
I'd make a set of the serial numbers of the second list, so that you can do efficient contains checks.
So:
var secondListSerials = {for (var entry in secondList) entry["serialNumber"]};
var firstListOnly = [for (var entry in firstList)
if (!secondListSerials.contains(entry["serialNumber"]) entry
];

how can we check wether similar elements are present in table in lua in minimum time complexity

if a table of N integer is present how to check if an element is repeating if present it shows message that table has repeating elements, if this is to be achieved in minimum time complexity
Hash table is the way to go (ie normal Lua table). Just loop over each integer and place it into the table as the key but first check if the key already exists. If it does then you have a repeat value. So something like:
values = { 1, 2, 3, 4, 5, 1 } -- input values
local htab = {}
for _, v in ipairs(values) do
if htab[v] then print('duplicate value: ' .. v)
else htab[v] = true end
end
With small integer values the table will use an array so will be O(1) to access. With larger and therefore sparser values the values will be in the hash table part of the table which can just be assumed to be O(1) as well. And since you have N values to insert this is O(N).
Getting faster than O(N) should not be possible since you have to visit each value in the list at least once.

How can I iterate over list items in Pandoc's lua-filter function?

Pandoc's lua filter makes it really easy to iterate over a document and munge the document as you go. My problem is I can't figure out how to isolate list item elements. I can find lists and the block level things inside each list item, but I can't figure out a way to iterate over list items.
For example let's say I had the following Markdown document:
1. One string
Two string
2. Three string
Four string
Lets say I want to make the first line of each list item bold. I can easily change how the paragraphs are handled inside OrderedLists, say using this filter and pandoc --lua-filter=myfilter.lua --to=markdown input.md
local i
OrderedList = function (element)
i = 0
return pandoc.walk_block(element, {
Para = function (element)
i = i + 1
if i == 1 then return pandoc.Para { pandoc.Strong(element.c) }
else return element end
end
})
end
This will indeed change the first paragraph element to bold, but it only changes the first paragraph of the first list item because it's iterating across all paragraphs in all list items in the list, not on each list item, then on each paragraph.
1. **One string**
Two string
2. Three string
Four string
If I separate the two list items into two separate lists again the first paragraph of the first item is caught, but I want to catch the first paragraph of every list item! I can't find anything in the documentation about iterating over list items. How is one supposed to do that?
The pandoc Lua filter docs have recently been updated with more info on the properties of each type. E.g., for OrderedList elements, the docs should say (it currently says items instead of content, which is a bug):
OrderedList
An ordered list.
content: list items (List of Blocks)
listAttributes: list parameters (ListAttributes)
start: alias for listAttributes.start (integer)
style: alias for listAttributes.style (string)
delimiter: alias for listAttributes.delimiter (string)
tag, t: the literal OrderedList (string)
So the easiest way is to iterate over the content field and change items therein:
OrderedList = function (element)
for i, item in ipairs(element.content) do
local first = item[1]
if first and first.t == 'Para' then
element.content[i][1] = pandoc.Para{pandoc.Strong(first.content)}
end
end
return element
end

How to remove all elements found in GROUP B to GROUP A in Lua

Let's say I have two groups defined in my Lua script
groupA = {"donkey", "goat", "eagle", "whale", "dolphine", "dog", "mosquito", ...}
groupB = {"goat", "mosquito", "donkey"}
After the remove operation, the value of groupA have no more elements: "goat", "mosquito", and "donkey"
How do I remove all items in groupA that are found in groupB. I know we can loop through the items and compare each one but I prefer any API or simple built in statements that solve this types of problem. The elements could also be any type like record.
There are no built-in operators that calculate set difference in Lua. You can do what you described and to speed up this process you can build a hash of elements from the second table and then iterate over the elements in the first table and check if they are present in the hash (of the elements in the second table).
If you end up using table.remove to remove elements from the first table while iterating, you need to be careful to iterate from the end, otherwise you may end up skipping elements you need to remove.
You can also check if some of the suggestions in this thread about set operators work for you.
local lookup = {}
for i, v in ipairs(groupB) do
lookup[v] = true
end
local answer = {}
for i, v in ipairs(groupA) do
if (not lookup[v]) then
table.insert(answer, v)
end
end
create a lookup table for the unique items in groupB
traverse groupA and lookup each item in the lookup table
add items from groupA not found in the lookup table to answer table
Note: this approach doesn't account for duplicates. For example, if groupB contains "goat" three times, and groupA contains "goat" four times, then answer will contain "goat" zero times.
After some time of researching, I found out that this simple subtraction in Lua works for groups (or table) to remove elements found in a group from another.
Ex.
groupA = groupA - groupB

Multiple entries for one element of table in lua

I am interested in inserting a table within a table in lua
mytable1={"apple","banana","grape"}
mytable2={"one","two","three"}
I want to insert mytable2 in position 4 of mytable1... so after the merger it should look somewhat like this
mytable1={"apple","banana","grape",{"one","two","three"}}
So far I tried it this way:
table.insert(mytable1,4,mytable2)
print(mytable[4])
the result is
table: 0x900b128 instead of mytable2..
I am quite confused.Please advice me where I am doing wrong and what is the right way to proceed.
this is how printing of a table works. Try out print(mytable1) or print(mytable2) and you see a similar output. You used the correct way of inserting that table. Just try out print(table1[4][1]). it should print "one"
Or to get all values try:
for index, value in ipairs(table1[4]) do
print(value);
end
this will print "one", "two" and "three"
Is possible:
tTable = { "apple", "banana", "grape", {"one", "two", "three"}}
tTable[1]
> apple
tTable[4][1]
> one
Print on table does not return it's values, but the indication that's it is a table and it's address.
Source: table inside table in Lua
Suppose you want to simply display everything in your table:
tTable = { "apple", "banana", "grape", {"one", "two", "three"}}
for k,v in pairs(tTable) do
if type(k) == "table" then
for _,i in ipairs(k) do
print(i)
end
else
print(v)
end
end
> apple
> banana
> grape
> one
> two
> three
You've done it correctly; You're just making incorrect assumptions about values, variables and print.
mytable2 is a variable name. You generally won't see variable names as strings except if you are debugging.
A table is a value. No value has a name. table.insert adds a value (or value reference) to a table. In this case, the value is a table so a reference to it is added to the table referenced by the mytable1 variable.
print calls tostring on its arguments. tostring on a table value returns what amounts to a unique identifier. print(mytable2) would print the same string as print(mytable1[4]) because both reference the same table.

Resources