Iterate over a list and add items another list SCALA - list

I have a list like this:
val list = List(("A", List("B", "C")),("B", List("A", "C", "D")))
And I want to return a list like this
newlist = List(("A","B",List("B","C")),("A","C",List("B","C")),("B","A",List("A", "C", "D")),("B","C",List("A", "C", "D")),("B","D",List("A", "C", "D")))
How can i do it with map? How can i do it with for?

This appears to be what you're after.
val lst = List(("A", List("B", "C")),("B", List("A", "C", "D")))
lst.flatMap{case (s,l) => l.map((s,_,l))}
res0: List[(String, String, List[String])] = List((A,B,List(B, C)), (A,C,List(B, C)), (B,A,List(A, C, D)), (B,C,List(A, C, D)), (B,D,List(A, C, D)))
As a for comprehension it might look like this.
for {
t <- lst //for every tuple from lst
s <- t._2 //for every string from tuple's 2nd element
} yield (t._1, s, t._2) //create new tuple (triple)

Related

How to convert List<String> to Map<String, Int> in Kotlin?

For example I have a list of strings like:
val list = listOf("a", "b", "a", "b" "a" "c")
and I need to convert it to a Map, where the strings are the keys and values are count of repetitions. So i have to got Map like [a = 3] [b = 2] [c = 1]
val list = listOf("a", "b", "a", "b", "a", "c")
val result = list.groupingBy { it }.eachCount()
// result is Map<String, Int> looking like this: {a=3, b=2, c=1}
Edit: for counts bigger than 1 add a filter condition to the map
val result = list.groupingBy { it }.eachCount().filter { it.value > 1 }
// result is now: {a=3, b=2}

Sort ArrayList based on Another ArrayList in kotlin

I have a list of String as below:-
val a = listOf("G", "F", "E", "D", "C", "B", "A")
I will get another list from the server. For example:-
val b = listOf("A", "G", "C")
List from the server may contain fewer elements or more elements but will not contain elements other than the first list.
So, after sorting output should be like
// G, C, A
You are not trying to sort, you are trying to filter
fun filterByServer(server: List<String>, local: List<String>)
= local.filter { value -> server.contains(value) }
filter takes a predicate in this case if your local value is contained on the server list
You can use map and sorted to achieve that easily on the condition that a do not have repetition -
val a = listOf("G", "F", "E", "D", "C", "B", "A")
val b = listOf("A", "G", "C")
val there = b.map{ v -> a.indexOf(v)}.sorted().map{v -> a[v]}
println(there)
Output:: [G, C, A]
Alternate sorter way as pointed by #jsamol in comment -
val there = b.sortedBy { a.indexOf(it) }
You can create a custom comparator based on the indices of letters in the a list. Then use the List.sortedWith function to sort the b list.
e.g.
val a = listOf("G", "F", "E", "D", "C", "B", "A")
val b = listOf("A", "G", "C")
val indexedA: Map<String, Int> = a.mapIndexed { index, s -> s to index }.toMap()
val comparator = object: Comparator<String> {
override fun compare(s1: String, s2: String): Int {
val i1 = indexedA[s1]
val i2 = indexedA[s2]
return if (i1 == null || i2 == null) throw RuntimeException("unable to compare $s1 to $s2")
else i1.compareTo(i2)
}
}
val c = b.sortedWith(comparator)
System.out.println(c)
I've converted the list a to a map: Letter to Index as an optimization.
If I understand the requirement, what we're really doing here is filtering the first list, according to whether its elements are in the second.  So another approach would be to do that explicitly.
val a = listOf("G", "F", "E", "D", "C", "B", "A")
val b = listOf("A", "G", "C").toSet() // or just setOf(…)
val there = a.filter{ it in b }
There's a bit more processing in creating the set, but the rest is faster and scales better, as there's no sorting or scanning, and checking for presence in a set is very fast.
(In fact, that would work fine if b were a list; but that wouldn't perform as well for big lists.)

How to delete "any" element of a list in elixir

I have a list of lists
>> list = [[1,""],[2,"b"],[3,""],[4,"c"]]
I want to delete the lists that contains "" element
>>list = [[2,"b"],[4,"c"]]
I'm trying to find something like
list = List.delete(list,[any,""])
You could combine Enum.reject/2 with Enum.member?/2 and reject any list that contains empty string
iex> Enum.reject([[1,""],[2,"b"],[3,""],[4,"c"]], &Enum.member?(&1, ""))
[[2, "b"], [4, "c"]]
If your inner lists are always the same two-item style and you're only wanting to check the second item, you could also use an anonymous function
iex> Enum.reject([[1,""],[2,"b"],[3,""],[4,"c"]], fn [_, b] -> b == "" end)
[[2, "b"], [4, "c"]]
or a comprehension that does pretty much the same thing
iex> for [a, b] when b != "" <- [[1,""],[2,"b"],[3,""],[4,"c"]], do: [a, b]
[[2, "b"], [4, "c"]]

Cartesian Product of a list of lists in Erlang

I have a list of lists (in erlang, strings are lists) which looks like this:
["abc","def"]
and I would like to get the following combinations in a list returned by a function:
["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
Is it possible with list-comprehension? I don't know the dimension of the list beforehand
If you don't know the dimension of the input, then you need to use recursion as #legoscia said:
cartesian([H]) -> [[A] || A <- H];
cartesian([H|T]) -> [[A|B] || A <- H, B <- cartesian(T)].
A 1-dim input "abc" is turned into ["a", "b", "c"], everything else is recursion.
> cartesian:cartesian(["abc", "def", "ghi"]).
["adg","adh","adi","aeg","aeh","aei","afg","afh","afi",
"bdg","bdh","bdi","beg","beh","bei","bfg","bfh","bfi","cdg",
"cdh","cdi","ceg","ceh","cei","cfg","cfh","cfi"]
Edit: Or easier, yet: Let a 0-dim argument return the set that contains the empty set. I think that's what a mathematician would do, too.
cartesian([H|T]) -> [[A|B] || A <- H, B <- cartesian(T)];
cartesian([]) -> [[]].
If you have exactly two lists, then you can do it with a list comprehension like this:
1> [[X,Y] || X <- "abc", Y <- "def"].
["ad","ae","af","bd","be","bf","cd","ce","cf"]
If you have an arbitrary number of lists, you could do it with a list comprehension inside a recursive function.

How to merge tuples by same elements in Scala

For example, if I have the following tuples:
(1, "a", "l")
(1, "a", "m")
(1, "a", "n")
I want to merge them like this:
(1, "a", List("l", "m", "n"))
In my case, the lists are a result from an inner join using Slick.
So, the first and second elements (1 and "a") should be the same.
If somebody knows how to merge like that in case of using Slick, let me know please.
Or more generally, the way to merge tuples with inner lists by the same elements.
(1, "a", "l")
(1, "a", "m")
(1, "b", "n")
(1, "b", "o")
// to like this
List( (1, "a", List("l", "m")), (1, "b", List("n", "o")) )
How about:
val l = ??? // Your list
val groups = l groupBy { case (a, b, c) => (a,b) }
val tups = groups map { case ((a,b), l) => (a,b,l.map(_._3)) }
tups.toList
You could try foldRight
val l = List((1, "a", "l"), (1, "a", "m"), (1, "a", "n"), (1, "b", "n"), (1, "b", "o"))
val exp = List((1, "a", List("l", "m", "n")), (1, "b", List("n", "o")))
val result = l.foldRight(List.empty[(Int, String, List[String])]) {
(x, acc) =>
val (n, s1, s2) = x
acc match {
case (n_, s1_, l_) :: t if (n == n_ && s1 == s1_) =>
(n_, s1_, (s2 :: l_)) :: t
case _ =>
(n, s1, List(s2)) :: acc
}
}
println(result)
println(result == exp)
Update
If the input list is not sorted:
val result = l.sorted.foldRight(...)