Как убрать каждый элемент в массиве после условного? - PullRequest
0 голосов
/ 10 февраля 2019

Итак, у меня есть массив строк в Scala, который называется произношение Array, например:

["EH1","N", "D", "P", "ER0", "EH1", "N", "TH", "AH0", "S", "IY2", "Z"]

, и я хочу написать оператор if else, который читает массив в обратном порядке, и как только он находит строкус числом в нем, он либо удаляет все строки после, либо помещает все ранее в отдельный массив.

, поэтому для приведенного выше примера id нужно, чтобы он остановился на «IY2», затем либо создайте новый массивс помощью только ["IY2", "Z"] или удалите каждую строку после и оставьте исходный массив с, как я уже сказал, ["IY2", "Z"].Само число не является целым числом между прочим, его частью строки, и числа находятся в диапазоне 0-2.

Я пробовал цикл в обратном порядке с if else, который ищет числа 0, 1,2, но возвращает каждую строку с номером, поэтому возвращает [IY2, AH0, EH1, ER0, EH1], но не останавливается, как только находит первую строку с номером.И я не уверен, как поместить все перед этой строкой в ​​новый массив, если я даже нашел способ остановить его.

for (sounds <- pronunciationArray.reverse) {

  val number0 = sounds.contains("0")

  if (number0 == true) {

    println(sounds)

  } else if (number0 == true){

    println(sounds)

  } else if (number1 == true){

    println(sounds)

  } else {

    -1

  }

}

Я хочу, чтобы он возвращал только ["IY2", "Z"] но вернул [IY2, AH0, EH1, ER0, EH1]

Ответы [ 3 ]

0 голосов
/ 10 февраля 2019

Один из алгоритмов, который вы можете решить, это

  • найти индекс элемента из последнего, где элемент имеет 0, 1 или 2
  • splitмассив с индексом выше
  • принимает последний элемент первого массива и весь второй массив

Пример,

val pronunciationArray = Array("EH1","N", "D", "P", "ER0", "EH1", "N", "TH", "AH0", "S", "IY2", "Z")

def takeUntil(inputArray: Array[String], condition: String => Boolean): Array[String] = {
  val findIndexFromLast = inputArray.reverse.zipWithIndex.collectFirst {
    case (elem, index) if condition.apply(elem) => index
  }

  findIndexFromLast match { // pattern match to check if there exists element with 0, 1, or 2
    case Some(indexFromLast) =>
      inputArray.splitAt(inputArray.length - indexFromLast) match {
        case (head, tail) => head.last +: tail
      }
    case None => // no element with 0, 1, 2 exists
      inputArray
  }
}

takeUntil(
  inputArray = pronunciationArray,
  condition = elem => elem.contains("0") || elem.contains("1") || elem.contains("2")) //gives [IY2, Z]

Другой способ решениято же самое, используя .span(predicate), который является лучшей версией .splitAt(index)

def takeUntil2(inputArray: Array[String]): Array[String] = {
  inputArray.reverse.span {
    element =>
      !element.contains("0") && !element.contains("1") && !element.contains("2")
  } match {
    case (head, tail) => tail.take(1) ++ head.reverse
  }
}

val result = takeUntil2(inputArray = pronunciationArray)

Теперь, используя способ scala, вы можете расширить Array, чтобы иметь пользовательскую функцию,

  implicit class ArrayOps(array: Array[String]) {
    def takeUntil(predicate: String => Boolean): Array[String] = {
      val splitAt = array.reverse.span(predicate.apply)
      splitAt._2.take(1) ++ splitAt._1.reverse
    }
  }

  val res = pronunciationArray
    .takeUntil(predicate = elem => !elem.contains("0") && !elem.contains("1") && !elem.contains("2"))

Аналогичный вопрос: Как реализовать 'takeUntil' списка?

Как мне сопоставить массивы соответствия в Scala?

0 голосов
/ 11 февраля 2019

Массивы Scala предлагают метод lastIndexWhere , который принимает предикат и возвращает индекс последнего элемента, который выполняет предикат:

val arr = Array("EH1","N", "D", "P", "ER0", "EH1", "N", "TH", "AH0", "S", "IY2", "Z")

val idx = arr.lastIndexWhere(e => e.intersect(Array('0', '1', '2')).size > 0)

, а затем вызывается метод takeRight для полученияжелаемый результат

val res = arr.takeRight(arr.size - idx)
0 голосов
/ 10 февраля 2019

Я не совсем понимаю вашу цель, но Array имеет функцию span, которая разбивает ее на две части в зависимости от условия - первая часть - это префикс массива, где все удовлетворяет условию ивторая часть - остаток.

Допустим, ваше условие состояло в том, что строка содержит 2, а не число (только потому, что я ленивый - это может быть любая функция f: String => Boolean).Если мы перевернем массив и затем разделим на отрицание функции, мы получим:

scala> a.reverse.span(!_.contains("2"))
res5: (Array[String], Array[String]) = (Array(Z),Array(IY2, S, AH0, TH, N, EH1, ER0, P, D, N, EH1))

Мы знаем, что первый элемент второго массива удовлетворяет нашему условию, поэтому мы можемпросто соберите результат:

scala> val (start, end) = a.reverse.span(!_.contains("2"))
start: Array[String] = Array(Z)
end: Array[String] = Array(IY2, S, AH0, TH, N, EH1, ER0, P, D, N, EH1)

scala> val result = end.take(1) ++ start.reverse
result: Array[String] = Array(IY2, Z)

Все развороты, возможно, не самые эффективные, но они выполняют свою работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...