How to convert ListBuffer to List (immutable collection ) in scala - list

I have the below code using ListBuffer but I want to use immutable collection like List and achieve the same result
val list1: ListBuffer[String] = ListBuffer("a", "b", "c")
val s= list1
.foldLeft(mutable.ListBuffer.empty[String]) { (strings, content) =>
{
if(StringUtils.isNotBlank(content))
strings += content
else
strings += "-"
}
}
.mkString(";")
Second version
val list1: ListBuffer[String] = ListBuffer("a", "b", "c")
val s= list1
.foldLeft(mutable.ListBuffer.empty[String]) { (strings, content) =>
{
strings += content
}
}
.mkString(";")

You can use collect
List("a", "b", "c").collect {
case c if StringUtils.isNotBlank(c) => c
case _ => "-"
}.mkString(";")

Related

How do I transform a List[String] to a List[Map[String,String]] given that the list of string represents the keys to the map in Scala?

I have a list of references:
val references: List[String]= List("S","R")
I also have variables which is:
val variables: Map[String,List[String]]=("S"->("a","b"),"R"->("west","east"))
references is a list of keys of the variables map.
I want to construct a function which takes:
def expandReplacements(references:List[String],variables:Map[String,List[String]]):List[Map(String,String)]
and this function should basically create return the following combinations
List(Map("S"->"a"),("R"->"west"),Map("S"->"a"),("R"->"east"),Map("S"->"b"),("R"->"west"),Map("S"->"b"),("R"->"east"))
I tried doing this:
val variables: Map[String,List[String]] = Map("S" -> List("a", "b"), "R" -> List("east", "central"))
val references: List[String] = List("S","R")
def expandReplacements(references: List[String]): List[Map[String, String]] =
references match {
case ref :: refs =>
val variableValues =
variables(ref)
val x = variableValues.flatMap { variableValue =>
val remaining = expandReplacements(refs)
remaining.map(rem => rem + (ref -> variableValue))
}
x
case Nil => List.empty
}
If you have more than 2 references, you can do:
def expandReplacements(references: List[String], variables :Map[String,List[String]]): List[Map[String, String]] = {
references match {
case Nil => List(Map.empty[String, String])
case x :: xs =>
variables.get(x).fold {
expandReplacements(xs, variables)
} { variableList =>
for {
variable <- variableList.map(x -> _)
otherReplacements <- expandReplacements(xs, variables)
} yield otherReplacements + variable
}
}
}
Code run at Scastie.
So I have Figured it Out
def expandSubstitutions(references: List[String]): List[Map[String, String]] =
references match {
case r :: Nil => variables(r).map(v => Map(r -> v))
case r :: rs => variables(r).flatMap(v => expandSubstitutions(rs).map(expanded => expanded + (r -> v)))
case Nil => Nil
}
This Returns:
List(Map(R -> west, S -> a), Map(R -> east, S -> a), Map(R -> west, S -> b), Map(R -> east, S -> b))
Your references representation is suboptimal but if you want to use it...
val variables: Map[String,List[String]] = [S -> List("a", "b"), R -> List("east", "central")]
val references: List[String] = List("S","R")
def expandReplacements(references: List[String]): List[Map[String, String]] =
references match {
case List(aKey, bKey) =>
val as = variables.get(aKey).toList.flatten
val bs = variables.get(bKey).toList.flatten
as.zip(bs).map { case (a, b) =>
Map(aKey -> a, bKey -> b)
}
case _ => Nil
}

Flutter Complex Sorting of a List

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();
}

Swift splitting "abc1.23.456.7890xyz" into "abc", "1", "23", "456", "7890" and "xyz"

In Swift on OS X I am trying to chop up the string "abc1.23.456.7890xyz" into these strings:
"abc"
"1"
"23"
"456"
"7890"
"xyz"
but when I run the following code I get the following:
=> "abc1.23.456.7890xyz"
(0,3) -> "abc"
(3,1) -> "1"
(12,4) -> "7890"
(16,3) -> "xyz"
which means that the application correctly found "abc", the first token "1", but then the next token found is "7890" (missing out "23" and "456") followed by "xyz".
Can anyone see how the code can be changed to find ALL of the strings (including "23" and "456")?
Many thanks in advance.
import Foundation
import XCTest
public
class StackOverflowTest: XCTestCase {
public
func testRegex() {
do {
let patternString = "([^0-9]*)([0-9]+)(?:\\.([0-9]+))*([^0-9]*)"
let regex = try NSRegularExpression(pattern: patternString, options: [])
let string = "abc1.23.456.7890xyz"
print("=> \"\(string)\"")
let range = NSMakeRange(0, string.characters.count)
regex.enumerateMatchesInString(string, options: [], range: range) {
(textCheckingResult, _, _) in
if let textCheckingResult = textCheckingResult {
for nsRangeIndex in 1 ..< textCheckingResult.numberOfRanges {
let nsRange = textCheckingResult.rangeAtIndex(nsRangeIndex)
let location = nsRange.location
if location < Int.max {
let startIndex = string.startIndex.advancedBy(location)
let endIndex = startIndex.advancedBy(nsRange.length)
let value = string[startIndex ..< endIndex]
print("\(nsRange) -> \"\(value)\"")
}
}
}
}
} catch {
}
}
}
It's all about your regex pattern. You want to find a series of contiguous letters or digits. Try this pattern instead:
let patternString = "([a-zA-Z]+|\\d+)"
alternative 'Swifty' way
let str = "abc1.23.456.7890xyz"
let chars = str.characters.map{ $0 }
enum CharType {
case Number
case Alpha
init(c: Character) {
self = .Alpha
if isNumber(c) {
self = .Number
}
}
func isNumber(c: Character)->Bool {
return "1234567890".characters.map{ $0 }.contains(c)
}
}
var tmp = ""
tmp.append(chars[0])
var type = CharType(c: chars[0])
for i in 1..<chars.count {
let c = CharType(c: chars[i])
if c != type {
tmp.append(Character("."))
}
tmp.append(chars[i])
type = c
}
tmp.characters.split(".", maxSplit: Int.max, allowEmptySlices: false).map(String.init)
// ["abc", "1", "23", "456", "7890", "xyz"]

Sort depending on variable in Scala

Is there any way in Scala to sort a list of objects by a specific field using a variable to set the order (ASC or DESC)?
I know with sortWith you can do something like
myList.sortWith((x, y) => x < y)
or
myList.sortWith((x, y) => x > y)
to sort ascending or descending, but I want to use a variable.
So, I tried something like this:
case class Person(firstName: String, LastName: String, age: Int)
private def sortDocuments(sortField: String, sortDirection: String, people: List[Person]): List[Person] = {
sortField match {
case "age" => people.sortBy(if (sortDirection == "desc") -_.age else _.age)
case "firstName" => people.sortWith { sortString(a.firstName, b.firstName, sortDirection) }
case "lastName" => people.sortWith { sortString(a.firstName, b.lastName, sortDirection) }
}
}
private def sortString(fieldA: String = null, fieldB: String = null, direction: String = "asc") = {
val fieldAVaild = Option(fieldA).getOrElse("")
val fieldBVaild = Option(fieldB).getOrElse("")
if (direction == "desc") fieldBVaild > fieldAVaild else fieldAVaild < fieldBVaild
}
But sortWith only receives a function with two parameters, so I get an error when I add the third parameter (sortDirection).
You forgot the (a, b) => expr part of the first/last name cases
case "firstName" => people.sortWith {(a, b) => sortString(a.firstName, b.firstName, sortDirection) }

How to count elements from list if specific key present in list using scala?

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)