Reorder elements in Erlang - erlang

I want to redefine the order of a tuple looking for specific words
Example, I have a list of tuples like this:
[{"a",["r001"]},
{"bi",["bidder"]},
{"bo",["an"]}]
But sometimes the order of the tuples can change for example:
[{"bi",["bidder"]},
{"a",["r001"]},
{"bo",["an"]}]
or
[{"bo",["an"]},
{"a",["r001"]},
{"bi",["bidder"]}]
The first string/list of the tuple is my unique key ("bo","a","bi")
But I want to be able to reorder the list of tuples, always like:
[{"a",["r001"]},
{"bi",["bidder"]},
{"bo",["an"]}]
How can I achieve this?

This will do it:
lists:sort(fun({A,_},{B,_}) -> A =< B end, List).
Or this, which will sort by the tuples second element after the first:
lists:sort(List).
I offer the second version, because without the custom sort function, it is faster for data like this.

If you need to sort by specified element, you just sort by specified element
lists:keysort(1, List).

Related

Lua: Sort table of numbers with multiple dots

I have a table of strings like this:
{
"1",
"1.5",
"3.13",
"1.2.5.7",
"2.5",
"1.3.5",
"2.2.5.7.10",
"1.17",
"1.10.5",
"2.3.14.9",
"3.5.21.9.3",
"4"
}
And would like to sort that like this:
{
"1",
"1.2.5.7",
"1.3.5",
"1.5",
"1.10.5",
"1.17",
"2.2.5.7.10",
"2.3.14.9",
"2.5",
"3.5.21.9.3",
"3.13",
"4"
}
How do I sort this in Lua? I know that table.sort() will be used, I just don't know the function (second parameter) to use for comparison.
Given your requirements, you probably want something like natural sort order. I described several possible solution as well as their impact on the results in a blog post.
The simplest solution may look like this (below), but there are 5 different solutions listed with different complexity and the results:
function alphanumsort(o)
local function padnum(d) return ("%03d%s"):format(#d, d) end
table.sort(o, function(a,b)
return tostring(a):gsub("%d+",padnum) < tostring(b):gsub("%d+",padnum) end)
return o
end
table.sort sorts ascending by default. You don't have to provide a second parameter then. As you're sorting strings Lua will compare the strings character by character. Hence you must implement a sorting function that tells Lua which comes first.
I just don't know the function (second parameter) to use for
comparison.
That's why people wrote the Lua Reference Manual
table.sort (list [, comp])
Sorts the list elements in a given order, in-place, from list1 to
list[#list]. If comp is given, then it must be a function that
receives two list elements and returns true when the first element
must come before the second in the final order, so that, after the
sort, i <= j implies not comp(list[j],list[i]). If comp is not given,
then the standard Lua operator < is used instead.
The comp function must define a consistent order; more formally, the
function must define a strict weak order. (A weak order is similar to
a total order, but it can equate different elements for comparison
purposes.)
The sort algorithm is not stable: Different elements considered equal
by the given order may have their relative positions changed by the
sort.
Think about how you would do it with pen an paper. You would compare each number segment. As soon as a segment is smaller than the other you know this number comes first.
So a solution would probably require you to get those segments for the strings, convert them to numbers so you can compare their values...

Java 8- forEach method iterator behaviour

I recently started checking new Java 8 features.
I've come across this forEach iterator-which iterates over the Collection.
Let's take I've one ArrayList of type <Integer> having values= {1,2,3,4,5}
list.forEach(i -> System.out.println(i));
This statement iteates over a list and prints the values inside it.
I'd like to know How am I going to specify that I want it to iterate over some specific values only.
Like, I want it to start from 2nd value and iterate it till 2nd last value. or something like that- or on alternate elements.
How am I going to do that?
To iterate on a section of the original list, use the subList method:
list.subList(1, list.length()-1)
.stream() // This line is optional since List already has a foreach method taking a Consumer as parameter
.forEach(...);
This is the concept of streams. After one operation, the results of that operation become the input for the next.
So for your specific example, you can follow #Joni's command. But if you're asking in general, then you can create a filter to only get the values you want to loop over.
For example, if you only wanted to print the even numbers, you could create a filter on the streams before you forEached them. Like this:
List<Integer> intList = Arrays.asList(1,2,3,4,5);
intList.stream()
.filter(e -> (e & 1) == 0)
.forEach(System.out::println);
You can similarly pick out the stuff you want to loop over before reaching your terminal operation (in your case the forEach) on the stream. I suggest you read this stream tutorial to get a better idea of how they work: http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/

Determine if record with field of certain value exists in list

I need to determine if a record with a given value exists in a list, what is the most efficient way to do this?
i think like this:
[ L || L = #record{state=determined} <- List ].
And the most efficient way is:
lists:any(fun(#record{state=deter}) -> true; (_) -> false end, List).
The first aproach is applicable if your list contains few records with determined field in the list and you'll get it all.
The second aproach is the most efficient because we are using standart library and if we'll get nedeed record we'll will stop iteration over the list.

mongoid: select elements that have at least n elements in array

In mongoid you can query items that have at least one element in array:
Item.any_in(tag_ids: [id1,id2,id3])
You can also select elements that have all elements in array:
Item.all_in(tag_ids: [id1,id2,id3])
My Question: Is there any way to query elements that have at least n elements in array ?
I'd like to query something like Item.at_least(tag_ids: [id1,id2,id3], n: 2) to return any Item that share at least two ids with [id1,id2,id3]
Thanks !
I don't know a pure Mongoid-solution. I also haven't found such query in the MongoDB manual: http://docs.mongodb.org/manual/reference/operator/query-array/
I would use some mix of Mongoid and array operations.
The disadvantage of it is, that all items which have at least 1 of these tags will be loaded.
searched_tag_ids = ['54253ad452656b1d25000000','54253adc52656b1d25010000','54253ae352656b1d25020000']
items_with_min_1_searched_tag = Item.any_in(tag_ids: searched_tag_ids).to_a
items_with_min_2_searched_tag = items_with_min_1_searched_tag.select{|item| (item.tag_ids.collect{|tag_id| tag_id.to_s} & searched_tag_ids).size >=2}

Sorting a list in Erlang

How does one sort a list in Erlang depending on a tag for each element?
If I have a process which loops and receives a single value from multiple processes and then I want to arrange the list according to the tag(which is an index) as an element is received.
How does one do this without using BIFs?
I currently do the following but would like to arrange the list when an element is added, like an insertion sort using the tags.
fibLoop(calcData) ->
receive
{Number, Tag} ->
fibLoop([{Number, Tag}|calcData]);
Something like this would probably work:
insert({_, Tag} = Data, [{_,HTag}|_] = List) when Tag >= HTag ->
[Data | List];
insert(Data, [H | T]) ->
[H | insert(Data, T)];
insert(Data, []) ->
[Data].
There are multiple ways to do what you want, a bit depending on what you want to use the value for later.
Easy solution would be to use gb_trees. gb_trees are a sorted structure that you can loop over using an iterator.
Or if you want to keep it simple and have a list you could use orddict (or possibly ordsets).
orddict:store(Number, Tag, CalcData)
to insert {Number, Tag} into an ordered list. See documentation for orddict for more information.
To get the smallest value in the list you can use hd/1, and to get the biggest lists:last/1 (not that I recommend lists:last, mind you).

Resources