Way of fast iterating through list - list

I have a question about iterating through lists.
Let's say i have list of maps with format
def listOfMaps = [ ["date":"2013/05/23", "id":"1"],
["date":"2013.05.23", "id":"2"],
["date":"2013-05-23", "id":"3"],
["date":"23/05/2013", "id":"4"] ]
Now i have a list of two patterns (in reality i have a lot more :D)
def patterns = [
/\d{4}\/\d{2}\/\d{2}/, //'yyyy/MM/dd'
/\d{4}\-\d{2}\-\d{2}/ //'yyyy-MM-dd'
]
I want to println dates only with the "yyyy/MM/dd" and "yyyy-MM-dd" format so i have to go through the lists
for (int i = 0; i < patterns.size(); i++) {
def findDates = listOfMaps.findAll{it.get("word") ==~ patterns[i] ?
dateList << it : "Nothing found"}
}
but i have a problem with this way. What if the list "listOfMaps" gonna be huge? It will take a lot of time to find all patters because this code will have to go through the whole list of patters and the same amount of time it will have to go through list of maps wich in case of huge lists might take a long while :). I tried with forEach inside the findAll clousure it does not work.
So my question is is there any way to go through the list of patterns inside the findAll clousure? For instance sth like this in pseudocode
def findDates = listOfMaps.findAll{it.get("word") ==~ for(){patterns[i]} ? : }
so in that case it goes only once through the listOfMaps list and it iterates through patterns(which always is way way way way smaller than listOfMaps).
I might have an idea to create a function that returns the instance of list, but i'm struggling to implement this :).
Thanks in advance for response.

You could do:
def listOfMaps = [ [date:"2013/05/23", id:"1"],
[date:"2013.05.23", id:"2"],
[date:"2013-05-23", id:"3"],
[date:"23/05/2013", id:"4"] ]
def patterns = [
/\d{4}\/\d{2}\/\d{2}/, //'yyyy/MM/dd'
/\d{4}\-\d{2}\-\d{2}/ //'yyyy-MM-dd'
]
def foundRecords = listOfMaps.findAll { m ->
patterns.find { p ->
m.date ==~ p
}
}

Related

Replace two characters in tuple element with dictionary value

I have a list of tuples (lot):
lot = [('490001', 'A-ARM1'),
('490001', 'A-ARM2'),
('490002', 'B-ARM3')]
Subsequently, I loop through every second tuple element and wish to replace every 'A-' and 'B-' characters by a dictionary value:
from more_itertools import grouper
dict = {'A-': 'ZZ', 'B-': 'XX'}
for el1, el2 in lot:
for i, j in grouper(el2, 2):
if i+j in dict:
lot2 = [ (el2.replace( (i+j), dict[i+j] )) for el1, el2 in lot ]
print(lot2)
After 'lot2 = ' something is going wrong, my output is
['A-ARM1', 'A-ARM2', 'XXARM3'] instead of [ZZARM1', 'ZZARM2', 'XXARM3']
Can anyone give me a hint on how to resolve this? Also, if you think I can write this more elegantly, feel free to let me know. I'm eager to learn. Any help is greatly appreciated.
This might not be the shortest solution, but it should work:
lot2 = []
for el1, el2 in lot:
lookup = el2[:2]
if lookup in dict:
lot2.append(dict[lookup] + el2[2:])
else:
lot2.append(el2)

What's the best way to find an object from a string in kotlin?

I have an app that is reading an ingredients list. At this point I've already retrieved a list of the 2500 most common ingredients. So I've got a list of, say 10 ingredients as strings, and a list of 2500 ingredients, with names as well as other properties. If an ingredient in this list of strings matches the name of an ingredient in the list of ingredients, I'd like to add it to another list third list, of ingredients that exist. The only way I know how to do that is with basically a for loop.
I'd do it as
fun compareLists(listOfIng: List<String>): List<ListIngredientsQuery.Item> {
var returnList = mutableListOf<ListIngredientsQuery.Item>()
for (ing in listOfIng) {
for (serverIngredient in MyApp.metaIngredientList!!) {
if (serverIngredient.name() == ing) {
returnList!!.add(serverIngredient)
}
}
}
return returnList
}
Which would technically work, but I have to imagine there's a better, faster way than iterating over 2500 items, as many times as there are Ingredients in an Ingredient list. What is the like, proper, preferred by real developers, way of doing this.
As each ingredient name is unique, you can use hash map for storing your 2500 ingredients with its name as the key. This way you do not need to loop over that huge collection any more, but just look thing up by the name and let the hash map deal with it.
To put some code to what Marcin said, here is what I would do:
fun compareLists(listOfIng: List<String>) =
MyApp.metaIngredientList!!
.associateBy { it.name() }
.let { metaIngredientMap -> listOfIng.mapNotNull { metaIngredientMap[it] }}
Or if we wanna avoid using !!
fun compareLists(listOfIng: List<String) =
MyApp.metaIngredientList
?.associateBy { it.name() }
?.let { metaIngredientMap -> listOfIng.mapNotNull { metaIngredientMap[it] }}
?: emptyList<ListIngredientQuery.Item>()
Of course, ideally, you would want that MyApp.metaIngredientList to be already a Map and not convert it into a Map for each operation

Groovy get all elements in a list under certain index

I want to collect all the elements in a specific array list under a specific index. Let's say I have this list:
def names = ["David", "Arthur", "Tommy", "Jacob"]
I want to print all the names under the index of 2, which in this case, will print "David, Arthur"
Now I can use a for loop quite easily with that or even groovy's eachWithIndex(). The problem is I don't want to run all over the elements because that's not efficient. Rather than that, I want to run until a specific point.
Is there any method in groovy which does that , because I didn't find one.
Thanks in advance!
Since you're starting at index 0, the take method is probably the simplest approach.
def names = ["David", "Arthur", "Tommy", "Jacob"]
assert ['David', 'Arthur'] == names.take(2)
Given the list
def names = ["David", "Arthur", "Tommy", "Jacob"]
you can use any of the options below:
assert [ "Tommy", "Jacob" ] == names[ 2..<4 ]
assert [ "Tommy", "Jacob" ] == names[ 2..-1 ]
assert [ "Tommy", "Jacob" ] == names.subList( 2, 4 )
assert [ "Tommy", "Jacob" ] == names.drop( 2 )
Note, that each of these methods create a new List instance, so if the memory considerations are of importance, it makes sense to skip the elements using e.g. eachWithIndex() method or alike
Using Ranges:
​def names = ["David", "Arthur", "Tommy", "Jacob"]
def idx = 2
def sublist = names[0..idx-1]
sublist.each { n ->
println n
}
Using more syntactic sugar:
names[0..<idx]

How to add elements in a list, list consists a hashmap (key value pair) in groovy

I have added hashmap to a list
Here is my list which consists of three different hashmaps.
{504=1111.07, 502=969.64, 501=823.43, 503=680.2, 512=669.03, 505=647.0}
{504=235.18, 502=205.24, 501=174.29, 503=143.98, 512=141.61, 505=136.95}
{504=235.18, 502=205.24, 501=174.29, 503=143.98, 512=141.61, 505=136.95}
I want to add all values with key as 504
Ex: 1111.07+235.18+235.18
How can i do this?
def list = [
[504:1111.07, 502:969.64, 501:823.43, 503:680.2, 512:669.03, 505:647.0],
[504:235.18, 502:205.24, 501:174.29, 503:143.98, 512:141.61, 505:136.95],
[504:235.18, 502:205.24, 501:174.29, 503:143.98, 512:141.61, 505:136.95]
]
assert list.sum { it[504] } == 1581.43
should do.

Erlang: List Comprehension to an Existing List

I am trying to create a new list via a list comprehension but want those new values to be included in an existing list.
More specifically, I am try to create a string out of the date and will have some string formatting between the values ( a dash - ). The existing list will be a template if you will with the dash.
Here is what I have so far:
{Date, Time} = erlang:universaltime().
DateList = tuple_to_list(Date).
DateListString = [ integer_to_list(X) || X < DateList ].
DateListStringConcatenate = lists:flatten(DateListString).
The result should be something along
"20101121"
But, what I want is
"2010-11-21"
So I am thinking about the DateListString comprehension "comprehending" to an existing list with "-" after the first and second element.
Any suggestions accompanied with concrete code samples much appreciated.
1> {{Y,M,D},_} = erlang:universaltime().
{{2010,11,21},{16,42,56}}
2> lists:flatten(io_lib:format("~p-~p-~p", [Y,M,D])).
"2010-11-21"
If you really want it in a list comprehension then you could do the following:
{Date, Time} = erlang:universaltime().
DateList = tuple_to_list(Date).
DateListString = [ [$- | integer_to_list(X)] || X <- DateList ].
[_ | DateListStringConcatenate] = lists:flatten(DateListString).
Roberto's is a better/more efficient solution to this but in case you wondered how you might do it with a list comprehension this would be one way.
This is a possible solution, but I feel that it is not an elegant one. Also, it does not use list comprehension.
1> {Date, Time} = erlang:universaltime().
{{2010,11,21},{14,51,23}}
2> DateList = tuple_to_list(Date).
[2010,11,21]
3> DateListString = lists:zipwith(fun(X,Y) -> integer_to_list(X) ++ Y end, DateList, ["-","-",""]).
["2010-","11-","21"]
4> DateListStringConcatenate = lists:flatten(DateListString).
"2010-11-21"