Scala замена для Arrays.binarySearch?
Есть ли замена в Scala для Java int Arrays.binarySearch(Object[] array, object)
?
Проблема заключается в том, что Scala Массивы не ковариантны, поэтому мне нужно было бы сделать мой stringArray: Array[String]
следующим образом:
stringArray.asInstanceOf[Array[Object]]
Есть ли лучшее решение?
Ответы
Ответ 1
По-моему, ничего не построено, но вы можете использовать рисунок pimp-my-library, чтобы выполнить это справедливо без труда. Например:
class ObjectArrayTools[T <: AnyRef](a: Array[T]) {
def binarySearch(key: T) = {
java.util.Arrays.binarySearch(a.asInstanceOf[Array[AnyRef]],key)
}
}
implicit def anyrefarray_tools[T <: AnyRef](a: Array[T]) = new ObjectArrayTools(a)
scala> Array("a","fish","is","some","thing").binarySearch("some")
res26: Int = 3
scala> Array("a","fish","is","some","thing").binarySearch("bye")
res28: Int = -2
Вы можете добавить другие методы объекта java.util.Arrays
в тот же класс, если они вам тоже нужны.
В общем, мне очень полезно привыкнуть к тому, чтобы всегда импортировать коллекцию ваших любимых утилит Scala. Легко добавить такие функциональные возможности, что вы можете сделать это в целом, а не печатать .asInstanceOf[Array[AnyRef]]
, и с небольшими усилиями вы можете сделать себя значительно более продуктивным.
Ответ 2
Scala 2.11 добавлен scala.collection.Searching
в стандартную библиотеку. В противном случае он использует двоичный поиск индексированных последовательностей и линейный поиск.
import scala.collection.Searching._
Array(1, 2, 3, 4, 5).search(3)
Ответ 3
Массивы - забавные звери. Если вы попробуете код в примере с ObjectArrayTools с помощью этого:
Array(1, 2, 3, 4, 5).binarySearch(3)
Вы получаете
error: value binarySearch is not a member of Array[Int]
Array(1, 2, 3, 4, 5).binarySearch(3)
Для того, что происходит с массивами в Scala, обратитесь к к этому документу. В любом случае вы могли бы использовать этот код вместо этого, хотя вместо Sequery он использует Seq. Тем не менее, у этого есть дополнительный бонус использования Ordering (который так и есть, также является Java Comparator. Поэтому вы можете настроить упорядоченное поведение, если это необходимо.)
import _root_.scala.collection.JavaConversions._
import java.util.{Collections, List => JList}
class SearchableSeq[T](a: Seq[T])(implicit ordering: Ordering[T]) {
val list: JList[T] = a.toList
def binarySearch(key: T): Int = Collections.binarySearch(list, key, ordering)
}
implicit def seqToSearchable[T](a: Seq[T])(implicit ordering: Ordering[T]) =
new SearchableSeq(a)(ordering)
Некоторые примеры:
scala> List(1, 2, 3, 4, 5).binarySearch(3)
res0: Int = 2
scala> List(1D, 2D, 3D, 4D, 5D).binarySearch(3.5)
res1: Int = -4
scala> List("a","fish","is","some","thing").binarySearch("bye")
res2: Int = -2
Ответ 4
Не так сложно просто написать его в scala
object BSearch {
def interative[T](array: Array[T], value: T)(implicit arithmetic: Numeric[T]): Int = {
var left: Int = 0;
var right: Int = array.length - 1;
while (right > left) {
val mid = left + (right - left) / 2
val comp = arithmetic.compare(array(mid), value)
if (comp == 0)
return mid; //negative if test < value
else if (comp > 0) //list(mid) > value
right = mid - 1;
else if (comp < 0) //list(mid) < value
left = mid + 1;
}
-1;
}
BSearch.interative(array, value)
Ответ 5
@Мойша-Беериина
Если вы собираетесь писать его в Scala, зачем писать его на Java в Scala? Почему бы не написать его в Scala?
def split(list:List[Char]): (List[Char], List[Char]) = {
val len = list.size
(list.slice(0, len/2), list.slice(len/2,len))
}
def search(target: Char, list: List[Char]):Boolean = {
list match {
case Nil => false
case head :: Nil => if (head == target) true else false
case _ => {
val c = split(list)
if (c._1.last >= target) search(target, c._1) else search(target, c._2)
}
}
}