0

I'm trying extract some values from a String. The string contains several lines with values. The values on each line are number, firstname, last name. Then I want to filter by a given pattern and remove the duplicate numbers.

This is my test:

test("Numbers should be unique") {
    val s = Cool.prepareListAccordingToPattern(ALLOWED_PATTERN, "1234,örjan,nilsson\n4321,eva-lisa,nyman\n1234,eva,nilsson")
    assert(s.length == 2, "Well that didn't work.. ")
    info("Chopping seems to work. Filtered duplicate numbers. Expected 1234:4321, got: "+s(0)(0)+":"+s(1)(0))
  }

The methods:

def prepareListAccordingToPattern(allowedPattern: String, s: String) : Array[Array[String]] = {
    val lines = chop("\n", s)
    val choppedUp = lines.map(line =>
      chop(",", line)).filter(array =>
        array.length == 3 && array(0).matches(allowedPattern)
      )    
    choppedUp
}

def chop(splitSymbol: String, toChop: String) : Array[String] = {
    toChop.split(splitSymbol)
  }

My test fails as expected since I receive back a multidimensional array with duplicates:

[0]["1234","örjan","nilsson"]

[1]["4321","eva-lisa","nyman"]

[2]["1234","eva","nilsson"]

What I would like to do is to filter out the duplicated numbers, in this case "1234" so that I get back:

[0]["1234","örjan","nilsson"]

[1]["4321","eva-lisa","nyman"]

How should I do this in a scala way? Maybe I could attack this problem differently?

2 Answers 2

1
val arr = Array(
  Array("1234","rjan","nilsson"),
  Array("4321","eva-lisa","nyman"),
  Array("1234","eva","nilsson")
)

arr.groupBy( _(0)).map{ case (_, vs) => vs.head}.toArray
// Array(Array(1234, rjan, nilsson), Array(4321, eva-lisa, nyman))

If you have a collection of elements (in this case Array of Array[String]) and want to get single element with every value of some property (in this case property is the first string from Array[String]) you should group elements of collection based on this property (arr.groupBy( _(0))) and then somehow select one element from every group. In this case we picked up the first element (Array[String]) from every group.

If you want to select any (not necessary first) element for every group you could convert every element (Array[String]) to the key-value pair ((String, Array[String])) where key is the value of target property, and then convert this collection of pairs to Map:

val myMap = arr.map{ a => a(0) -> a }.toMap
// Map(1234 -> Array(1234, eva, nilsson), 4321 -> Array(4321, eva-lisa, nyman))

myMap.values.toArray
// Array(Array(1234, eva, nilsson), Array(4321, eva-lisa, nyman))

In this case you'll get the last element from every group.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! This is what I was looking for! I ended up doing: choppedUp.map{ a => a.head -> a }.toMap
0

A bit implicit, but should work:

val arr = Array(
     Array("1234","rjan","nilsson"),
     Array("4321","eva-lisa","nyman"),
     Array("1234","eva","nilsson")
     )
arr.view.reverse.map(x => x.head -> x).toMap.values
// Iterable[Array[String]] = MapLike(Array(1234, rjan, nilsson), Array(4321, eva-lisa, nyman))

Reverse here to override "eva","nilsson" with "rjan","nilsson", not vice versa

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.