0

I am trying to do it as follows:

def contains(x: Int, l: List[Int]) = l match { // this is just l.contains(x)
  case _ :: x :: _ => true
  case _ => false
}

Unfortunately it does not work

scala> contains(0, List(1, 2, 3))
res21: Boolean = true

scala> contains(1, List(1, 2, 3))
res22: Boolean = true

scala> contains(3, List(1, 2, 3))
res23: Boolean = true

Could you please explain why ?

5 Answers 5

2

To match a number equal to x you can put it into backticks:

def contains(x: Int, l: List[Int]) = l match {
  case _ :: `x` :: _ => true
  case _ => false
}

Unfortunately :: matcher takes exactly one item from list – the first one, so this code would work only to find the second item in l:

scala> contains(1, List(1,2,3))
res2: Boolean = false

scala> contains(2, List(1,2,3))
res3: Boolean = true

scala> contains(3, List(1,2,3))
res4: Boolean = false

I believe, you can't match for an arbitrary item in a list without recursion:

def contains(x: Int, l: List[Int]): Boolean = l match { // this is just l.contains(x)
  case `x` :: xs => true
  case _ :: xs => contains(x, xs)
  case _ => false
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for reminding me about backticks. It is a pity that :: takes exactly one item :(
1

The first case matches any item in a non empty list, note,

scala> contains(123, List(1, 2, 3))
res1: Boolean = true

scala> contains(123, List())
res2: Boolean = false

A recursive method that matches against the head item of the list may work.

1 Comment

Thank you. Unfortunately I do not want recursion.
1

First, x in case section is alias for local variable. It's not x you passed to method.

Second, _ :: x :: _ matches any list with two elements and more. So all your outputs is true.

Comments

1

This might work,

  def contains(y: Int, l: List[Int]) = l match { // this is just l.contains(x)
    case _ :: x :: _  if(x == y)=> true
    case _ => false
  }

3 Comments

Great ! Thanks. Can I get rid of this if(x == y) somehow ?
@Michael, Why you don't want that guard condition?
Just for aesthetic reasons
1

Your approach does not work, because the x in the pattern match is bound to whatever value the second list element has. It's basically a fresh variable.

Alternative to S.K's answer

def contains(y: Int, l: List[Int]) = l match { // this is just l.contains(x)
  case _ :: x :: _  => x == y
  case _ => false
}

or you can also write

def contains[A](y: A, l: Seq[Int]) = (l.lift)(1).exists(_ == y)

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.