I have the following list:
List(List(("hello", "goodbye", 12), ("hello", "goodbye", 15)), List(("hello", "test", 18), ("hello", "test", 20)), List(("something", "different", 30), ("something", "different", 18)))
I would like to get the following result:
List(("hello", "goodbye", 27), ("hello", "test", 38), ("something", "different", 48))
I've tried to use .map and .groupBy, but I can't seem to find a way to get it working.
This appears to get what you're after as long as the order of result elements is unimportant.
val data =
List(List(("hello", "goodbye", 12), ("hello", "goodbye", 15)), List(("hello", "test", 18), ("hello", "test", 20)), List(("something", "different", 30), ("something", "different", 18)))
data.flatten
.groupMapReduce(tup => (tup._1,tup._2))(_._3)(_+_)
.map{case ((k1,k2),v) => (k1,k2,v)}
.toList
//res0: List[(String, String, Int)] =
// List((hello,test,38), (something,different,48), (hello,goodbye,27))
Notice that I flatten away all the inner sub-Lists and focus only on the String elements in the tuples. It's not completely clear if that's what you intend.
You can:
Flatten those lists into a single list
Group by the first two elements of each list
Reduce on the third element of each list in each group
val list = List(
List(("hello", "goodbye", 12), ("hello", "goodbye", 15)),
List(("hello", "test", 18), ("hello", "test", 20)),
List(("something", "different", 30), ("something", "different", 18))
)
val result = list.flatten.groupBy { case (s1, s2, _) => (s1, s2) }.values.map(_.reduce((s1, s2) => (s1._1, s1._2, s1._3 + s2._3)))
// List((hello,test,38), (hello,goodbye,27), (something,different,48))
If inner list can have different "keys" - you can flatten your list of lists with flatMap(identity) or flatten then group the result using first two elements of the tuples and reduce the groupping with sum:
val collection = ...
collection
.flatten
.groupMapReduce(t => (t._1, t._2))(identity)((l,r) => (l._1, l._2, l._3+r._3))
.values
.toList
Related
I have
>> list = ["a","b","c"]
and I need to get the index of the elements and create a new list that follows
>> list_2 = [[1,"a"], [2,"b"], [3,c]]
to create the new list I used
lista = Enum.flat_map(list, fn x -> [index,x] end)
but I can't find a function like to get the "index" value
list = ["a","b","c"]
list_2 = Enum.with_index(list)
gives
[{"a", 0}, {"b", 1}, {"c", 2}]
Enum.zip/2 is your friend here.
list = ~w[a b c]
#⇒ ["a", "b", "c"]
list_2 = Enum.zip(1..3, list)
#⇒ [{1, "a"}, {2, "b"}, {3, "c"}]
or, if the size is unknown upfront, you might
Enum.zip(Stream.iterate(1, & &1 + 1), list)
#⇒ [{1, "a"}, {2, "b"}, {3, "c"}]
to get a lists, not tuples, simply map the result
1
|> Stream.iterate(& &1+1)
|> Enum.zip(list)
|> Enum.map(&Tuple.to_list/1)
#⇒ [[1, "a"], [2, "b"], [3, "c"]]
Another way would be to use Enum.with_index/1
list
|> Enum.with_index(1)
|> Enum.map(fn {e, i} -> [i, e] end)
#⇒ [[1, "a"], [2, "b"], [3, "c"]]
I know the below answer is not related to asked question, but I'm sure it will help some in the feature.
In my case, I have to add an index to an array of lists/map.
So I did the below:
formatted_list = [%{"map 1": 1}, %{"map 2": 2}]
list_with_index = formatted_list
|> Enum.with_index(1)
|> Enum.map(fn {e, i} -> Map.put(e, :index, i) end)
Result:
[
{
"index": 1,
"map 1": 1
},
{
"index": 2,
"map 2": 2
}
]
I have two Lists
List 1 contains an object. One of the aspects of that object is a person ID [1,2,3,4,5] and List 2 contains the person ID's whom match a criteria [1,3,5]
I need to filter list 1 to only show the objects where the criteria is met.
Something like:
var sortedList = list1
.where((item) => item.personID == "Any of the ids contained within list2)
.toList();
Therefore sortedList = the objects for id 1,3,5
Short answer
Iterable<Item> filteredList = list.where((element) {
return list2
.map((elem) => elem.personId)
.toList()
.contains(element.personId);
});
You may look into this Dart Playground. Dartpad
Full Script
class Item {
int personId;
Item({this.personId});
String toString() {
return "$personId";
}
}
List<Item> list = [
Item(personId: 1),
Item(personId: 2),
Item(personId: 3),
Item(personId: 4),
Item(personId: 5),
];
List<Item> list2 = [
Item(personId: 1),
Item(personId: 3),
Item(personId: 5),
];
void runFunction() {
Iterable<Item> filteredList = list.where((element) {
return list2
.map((elem) => elem.personId)
.toList()
.contains(element.personId);
});
List<Item> result = filteredList.toList();
print(result);
}
main() {
runFunction();
}
I have a 2 list of following class
case class User(var userId: Int =0,
var userName: String ="",
var email: String="",
var password: String ="") {
def this() = this(0, "", "", "")
}
globalList of User class.
localList of User class.
I would like to remove/filter all items from globalList that are same userId in localList.
I tried couple of api with no success such as filterNot, filter, drop, dropWhile. Please advice me how it can be done.
The diff operator "Computes the multiset difference between this list and another sequence".
scala> val global = List(0,1,2,3,4,5)
global: List[Int] = List(0, 1, 2, 3, 4, 5)
scala> val local = List(1,2,3)
local: List[Int] = List(1, 2, 3)
scala> global.diff(local)
res9: List[Int] = List(0, 4, 5)
You can try the following:
val userIdSet = localList.map(_.userId).toSet
val filteredList = globalList.filterNot(u => userIdSet.contains(u.userId))
I have following list structure -
"disks" : [
{
"name" : "A",
"memberNo" :1
},
{
"name" : "B",
"memberNo" :2
},
{
"name" : "C",
"memberNo" :3
},
{
"name" : "D",
}
]
I have many elements in list and want to check for 'memberNo', if it exists
I want count of from list elements.
e.g. here count will be 3
How do I check if key exists and get count of elements from list using scala??
First create class to represent your input data
case class Disk (name : String, memberNo : String)
Next load data from repository (or other datasource)
val disks: List[Disk] = ...
And finally count
disks.count(d => Option(d.memberNo).isDefined)
In a similar fashion as in #SergeyLagutin answer, consider this case class
case class Disk (name: String, memberNo: Option[Int] = None)
where missing memberNo are defaulted with None; and this list,
val disks = List( Disk("A", Some(1)),
Disk("B", Some(2)),
Disk("C", Some(3)),
Disk("D"))
Then with flatMap we can filter out those disks with some memberNo, as follows,
disks.flatMap(_.memberNo)
res: List[Int] = List(1, 2, 3)
Namely, for the counting,
disks.flatMap(_.memberNo).size
res: Int = 3
Likewise, with a for comprehension,
for (d <- disks ; m <- d.memberNo) yield m
res: List[Int] = List(1, 2, 3)
I know this is probably a very simple List operation in Scala, but I'm a newbie and can't figure it out. I have a query that returns a result set with a series of values, grouped by a common id. For example:
Result Set:
[{ 1, "a", 30 },
{ 1, "b", 20 },
{ 1, "c", 22 },
{ 2, "a", 32 },
{ 2, "c", 10 }]
and what I'd like to do is put this into a map as such:
1 -> [{"a", 30}, {"b", 20}, {"c", 22}]
2 -> [{"a", 32}, {"c", 10}]
I think the collect method can be used for this but can't figure it out.
I'm not sure what the types in your data structure are, but maybe you can adapt this. This assumes you have a collection of tuples:
val items =
List((1, "a", 30),
(1, "b", 20),
(1, "c", 22),
(2, "a", 32),
(2, "c", 10))
items
.groupBy{ case (a,b,c) => a }
.mapValues(_.map{ case (a,b,c) => (b,c) })
// Map(1 -> List((a,30), (b,20), (c,22)), 2 -> List((a,32), (c,10)))
Or, more succinctly:
items.groupBy(_._1).mapValues(_.map(t => (t._2, t._3)))
The collect method is something else entirely (basically, it's map that drops non-matching values). The groupBy method is what you were really looking for.