Kundan Kumar
Kundan Kumar

Reputation: 2002

How to check whether all elements in list are numeric?

I have a data in this form, this is basically a huge data.

val data: Array[(Int, Iterable[String])] =
  Array(
    (34,List("sdkfj",7, 2, 5, 3, 1, 9, 2, 1, 4)),
    (4,List(7, 14, 4, 5, 11, 9, 5, 4, 1))
  )

I want to apply a function say isNumeric on the iterable items which should return me the output in the following way

Array((34,false), (4,true))

Basically, I want a false if any element in the list is not numeric, otherwise true.

I have tried this function

def isNumeric(input: String): Boolean = input.forall(_.isDigit)

But in this case I get a list of booleans whereas I want a single boolean result for the entire list.

Upvotes: 2

Views: 1528

Answers (1)

Marth
Marth

Reputation: 24812

You need to call .forall on the inner list :

scala> def isNumeric(input: String): Boolean = input.forall(_.isDigit)
isNumeric: (input: String)Boolean

scala> val a:Array[(Int,List[String])] = Array((34,List("sdkfj","7", "2", "5", "3", "1", "9", "2", "1", "4")), (4,List("7", "14", "4", "5", "11", "9", "5", "4", "1")))
a: Array[(Int, List[String])] = Array((34,List(sdkfj, 7, 2, 5, 3, 1, 9, 2, 1, 4)),
                                      (4, List(7, 14, 4, 5, 11, 9, 5, 4, 1)))

scala> a.map { case (k, l) => (k, l.forall(isNumeric)) }
res0: Array[(Int, Boolean)] = Array((34,false), (4,true))

EDIT

If you want to skip the validation for certain elements, you can use .filter before using .forall (running the validations only on the sublist) :

scala> val a:Array[(Int,List[String])] = Array((34,List("NA","7", "3")))
a: Array[(Int, List[String])] = Array((34,List(NA, 7, 3)))

// Not sure what an NA is, so...
scala> def isNA(s:String) = s == "NA"
isNA: (s: String)Boolean

// Using .filterNot here since you want to exclude all `NA`s
// You can also use .filter(!isNA(_)) 
// or .withFilter(!isNA(_)) which should be faster/more efficient
scala> a.map{ case (k, l) => (k, l.filterNot(isNA).forall(isNumeric)) }
res0: Array[(Int, Boolean)] = Array((34,true))

Note that you could also change the .isNumeric method to .isNumericOrNA (thereby skipping the need for a filter), although it might be a bit confusing, depending on what NA is.

NB: See the Scala API for an explanation of the differences between .filter and .withFilter.

Upvotes: 5

Related Questions