mop
mop

Reputation: 433

how to delete the elements that have the same prefix String (2 to 5 Chars) in a List?

there is a List as below:

val a: List[String] = List(aaaaa1, aaaaa2, bb, cc, dd1, ee, dd2, dd3, ff, ggg1, ggg2, aaaaa3)

how to delete the elements that have the same prefix String (2 to 5 Chars) in a List?

for example:

"aaaaa1","aaaaa2","aaaaa3" have the same prefix String "aaaaa"(5 Chars). so delete them.

"dd1","dd2","dd3" have the same prefix String "dd"(2 Chars). so delete them.

"ggg1","ggg2" have the same prefix String "ggg"(3 Chars). so delete them.

expected:

val b: List[String] = List(bb,cc,ee,ff)

==========

thx for your idea. now fix it.

a.foldLeft(scala.collection.mutable.LinkedHashMap[String,Int]().withDefaultValue(0)){
  case(m,e) =>
    val k = e.take(2)
    m(k)+=1
    m
}.filter(_._2==1).keys.toList

Upvotes: 2

Views: 127

Answers (3)

jwvh
jwvh

Reputation: 51271

Try this.

a.groupBy(_.take(2)).values.collect{case x if x.length == 1 => x.head}
// res0: Iterable[String] = List(cc, bb, ee, ff)

The original order is not retained because the collection passes through a Map() phase which, by definition, has no intrinsic order.


update

The original order can be preserved but it requires a two-step procedure.

val uniqPrefix = a.groupBy(_.take(2)).mapValues(_.length == 1)
a.filter(x => uniqPrefix(x.take(2)))
// res0: List[String] = List(bb, cc, ee, ff)

Upvotes: 2

mkUltra
mkUltra

Reputation: 3068

I think this code can be used in this case:

val list = List(
"aaaaa1", "aaaaa2", "bb", "cc", "dd1", "ee", "dd2", "dd3", "ff", "ggg1", "ggg2", "aaaaa3")

val prefix2items = list.groupBy(_.take(2))

list.filter(item => prefix2items(item.take(2)).length == 1) 
//res0: List[String] = List(bb, cc, ee, ff)

Upvotes: 1

Muhunthan
Muhunthan

Reputation: 413

This would work even if you have multiple character in prefix

The prefix will be identify until get a digit, the character after digit will not consider as prefix here

val a = List("abb1","abbbbbb1","aaaaa2","aaaaa3","aaaaaa44")

"abb1" will be removed here

a.filter(_.takeWhile(data => !data.isDigit).groupBy(_.toChar).values.exists{case x if (2 to 5).contains(x.length) => true case _ => false})

Upvotes: 0

Related Questions