list to match another nested list - nested-lists

second list sorted according to the first
[['E', 'E', 'C], ['B', 'C', 'A'], ['E', 'B', 'F'], ['D', 'F', 'E']]

ref_list = ['c','b','a']
# sort [1,2,3] according to ref_list... viz: ['c','a','b'] => [3,1,2]
ordering = sorted(range(len(ref_list)), key=lambda i: ref_list[i])
for j in range(len(list2)):
list2[j] = [list2[j][i] for i in ordering]

Here is some quick code I made, it works but it may need some refactoring:
def getListIndexes(some_list):
return [x for x in enumerate(some_list)]
list1 = [['C', 'B', 'A']]
list2 = [['C', 'E', 'E'], ['C', 'B', 'A'], ['F', 'B', 'E'], ['E', 'F', 'D']]
values_before_1 = getListIndexes(list1[0])
values_after_1 = getListIndexes(list(sorted(list1[0])))
mapping = dict.fromkeys(list(range(len(list1[0]))))
for item in values_before_1:
before, then = [(item[0],x[0]) for i, x in enumerate(values_after_1) if item[1]==x[1]][0]
mapping[then] = before
results = [[None, None, None] for l in range(len(list2))]
for i, item in enumerate(list2):
values = getListIndexes(item)
for j in range(len(item)):
results[i][mapping[j]] = list2[i][j]
print "[*] list1 with content: {} has been sorted and now is like: {}\n".format(list1[0], sorted(list1[0]))
print "[*] list2 with content:\n\n{}\n".format(list2)
print "...has been sorted based on list1 sorting and now looks like this...\n"
print results
Output:
[*] list1 with content: ['C', 'B', 'A'] has been sorted and now is like: ['A', 'B', 'C']
[*] list2 with content:
[['C', 'E', 'E'], ['C', 'B', 'A'], ['F', 'B', 'E'], ['E', 'F', 'D']]
...has been sorted based on list1 sorting and now looks like this...
[['E', 'E', 'C'], ['A', 'B', 'C'], ['E', 'B', 'F'], ['D', 'F', 'E']]

Related

Sorting by alphabet List of Lists

I had an exercise where I had to put duplicate elements from List to individual lists. Everything works fine, but my question is how to order it alphabetic now, so the result starts from List(a,a,a,a,a,a), not from List(e,e,e,e)
Tried to use sortBy in the end, but none combination worked for me.
My code:
val list2 = List('a', 'a', 'a', 'a', 'b', 'c', 'c', 'a', 'a', 'd', 'e', 'e', 'e', 'e')
def sortedSublist(l: List[Char]): List[List[Char]] = {
l.groupBy(identity).map{case (key, values) => values}.toList
}
println(sortedSublist(list2))
Current result is:
List(List(e, e, e, e), List(a, a, a, a, a, a), List(b), List(c, c), List(d))
mck suggested a good answer.
You can also sort the map by key after groupBy
l.groupBy(identity).toList.sortBy(_._1).map(_._2)

Dart combine two Lists in Alternate manner

I am trying to populate a ListView in Flutter with different sources. So, I have two lists,
list1 = ['a', 'b', 'c']; #The list isn't of numeric type
list2 = ['2', '4'];
Now, I can combine them using the spread operator and get the following output
[a, b, c, 2, 4]
but I want the output to be like -
[a, 2, b, 4, c]
How can this be achieved? What's the most idiomatic approach?
Builtin Iterable has no method zip, but you can write something like:
Iterable<T> zip<T>(Iterable<T> a, Iterable<T> b) sync* {
final ita = a.iterator;
final itb = b.iterator;
bool hasa, hasb;
while ((hasa = ita.moveNext()) | (hasb = itb.moveNext())) {
if (hasa) yield ita.current;
if (hasb) yield itb.current;
}
}
then use zip
final list1 = ['a', 'b', 'c'];
final list2 = ['2', '4'];
final res = zip(list1, list2);
print(res); // (a, 2, b, 4, c)
I guess this:
List list1 = [1, 3, 5];
List list2 = [2, 4];
print([...list1, ...list2]..sort());

scala intersection with count

I have a simple question, suppose I have 2 RDDs:
RDD1: [a,b,b,c,c,c,d] RDD2:[a,b,c,d]
and I want to find out how many a,b,c,d are there such that the returned results should be something like:
RDD:[(a,b,c,d),(1,2,3,1)]
It can be easily done using Lists, but in RDD, I seem to have to collect them first into Array and do something like:
count(_==string)
is there something easier that I could work with?
I have very Less knowledge about RDD or Spark. but in scala you can try something like this :
val l1 = List('a', 'b', 'c', 'd')
val l2 = List('a', 'b', 'b', 'c', 'c', 'c', 'd')
def f(l1: List[Char], l2: List[Char]):(List[Char],List[Int]) = {
val count = l1.map {
x => l2.count(_ == x)
}.toList
(l1, count)
}
f(l1,l2)
Output at REPL :
res0: (List[Char], List[Int]) = (List(a, b, c, d),List(1, 2, 3, 1))

Create an array of object using a for loop in coffescript

Quick question. I can't find the syntax for it (well assuming it exists) for creating an object from a for loop. What is the correct way to do this -
letters = ['a', 'b', 'c']
objs = (letter[index]:index for letter, index in letters)
#Also tryed..
objs = ({letter[index]:index} for letter, index in letters)
Any ideas?
coffee> letters = ['a', 'b', 'c']
[ 'a', 'b', 'c' ]
coffee> lettersToIndex = {}
{}
coffee> lettersToIndex[letter] = index for letter, index in letters
[ 0, 1, 2 ]
coffee> lettersToIndex
{ a: 0, b: 1, c: 2 }

padTo error inside a foldLeft

I'm learning myself Scala and one of the small test application I wrote just isn't working the way I expect it to. Can someone please help me understand why my test application is failing.
My small test application consists of a "decompress" method that does the following "decompression"
val testList = List(Tuple2(4, 'a'), Tuple2(1, 'b'), Tuple2(2, 'c'), Tuple2(2, 'a'), Tuple2(1, 'd'), Tuple2(4, 'e'))
require(decompress(testList) == List('a', 'a', 'a', 'a', 'b', 'c', 'c', 'a', 'a', 'd', 'e', 'e', 'e', 'e'))
In other words the Tuple2 objects should just be "decompressed" into a more verbose form. Yet all that I get back from the method is List('a', 'a', 'a', 'a') - the padTo statement works for the first Tuple2 but then it just suddenly stops working? If I however do the padding per element using a for loop - everything works...?
The full code:
object P12 extends App {
def decompress(tList: List[Tuple2[Int,Any]]): List[Any] = {
val startingList: List[Any] = List();
val newList = tList.foldLeft(startingList)((b,a) => {
val padCount = a._1;
val padElement = a._2;
println
println(" Current list: " + b)
println(" Current padCount: " + padCount)
println(" Current padElement: " + padElement)
println(" Padded using padTo: " + b.padTo(padCount, padElement))
println
// This doesn't work
b.padTo(padCount, padElement)
// // This works, yay
// var tmpNewList = b;
// for (i <- 1 to padCount)
// tmpNewList = tmpNewList :+ padElement
// tmpNewList
})
newList
}
val testList = List(Tuple2(4, 'a'), Tuple2(1, 'b'), Tuple2(2, 'c'), Tuple2(2, 'a'), Tuple2(1, 'd'), Tuple2(4, 'e'))
require(decompress(testList) == List('a', 'a', 'a', 'a', 'b', 'c', 'c', 'a', 'a', 'd', 'e', 'e', 'e', 'e'))
println("Everything is okay!")
}
Any help appreciated - learning Scala, just can't figure out this problem on my own with my current Scala knowledge.
The problem is that padTo actually fills the list up to a given size. So the first time it works with 4 elements padded, but the next time you'll have to add the actual length of the curent list - hence:
def decompress(tList: List[Tuple2[Int,Any]]): List[Any] = {
val newList = tList.foldLeft(List[Any]())((b,a) => {
b.padTo(a._1+b.length, a._2)
})
newList
}
You could do your decompress like this:
val list = List(Tuple2(4, 'a'), Tuple2(1, 'b'), Tuple2(2, 'c'), Tuple2(2, 'a'), Tuple2(1, 'd'), Tuple2(4, 'e'))
list.flatMap{case (times, value) => Seq.fill(times)(value)}
This works:
scala> testList.foldLeft(List[Char]()){ case (xs, (count, elem)) => xs ++ List(elem).padTo(count, elem)}
res7: List[Char] = List(a, a, a, a, b, c, c, a, a, d, e, e, e, e)
The problem actually is that when you say b.padTo(padCount, padElement) you use always the same list (b) to fill up the elements. Because the first tuple data generate the most elements nothing is added in the next step of foldLeft. If you change the second tuple data you will see a change:
scala> val testList = List(Tuple2(3, 'a'), Tuple2(4, 'b'))
testList: List[(Int, Char)] = List((3,a), (4,b))
scala> testList.foldLeft(List[Char]()){ case (xs, (count, elem)) => xs.padTo(count, elem)}
res11: List[Char] = List(a, a, a, b)
Instead of foldLeft you can also use flatMap to generate the elements:
scala> testList flatMap { case (count, elem) => List(elem).padTo(count, elem) }
res8: List[Char] = List(a, a, a, a, b, c, c, a, a, d, e, e, e, e)
By the way, Tuple(3, 'a') can be written (3, 'a') or 3 -> 'a'
Note that padTo doesn't work as expected when you have data with a count of <= 0:
scala> List(0 -> 'a') flatMap { case (count, elem) => List(elem).padTo(count, elem) }
res31: List[Char] = List(a)
Thus use the solution mentioned by Garret Hall:
def decompress[A](xs: Seq[(Int, A)]) =
xs flatMap { case (count, elem) => Seq.fill(count)(elem) }
scala> decompress(List(2 -> 'a', 3 -> 'b', 2 -> 'c', 0 -> 'd'))
res34: Seq[Char] = List(a, a, b, b, b, c, c)
scala> decompress(List(2 -> 0, 3 -> 1, 2 -> 2))
res35: Seq[Int] = List(0, 0, 1, 1, 1, 2, 2)
Using a generic type signature should be referred in order to return always correct type.