Получить индексы из одного массива и обновить элементы по тем же индексам во втором массиве - PullRequest
0 голосов
/ 07 августа 2020

У меня есть два массива, верхняя и нижняя границы.

val solution : Array[Double] = Array(1.0, 33.0, 31.0, 82.0, 51.0, 25.0, 39.0, 96.0, 95.0, 49.0)
val original : Array[Double] = Array(3.0, 45.0, 18.0, 25.0, 99.0, 6.0, 36.0, 61.0, 82.0, 62.0)
val lower = 30
val upper = 90

Массив типа Boolean создается с использованием решения массива.

val idx_lowest : Array[Boolean]  = solution.map ( x => x < lower )
idx_lowest: Array[Boolean] = Array(true, false, false, false, false, true, false, false, false, false)

Найти индексы в idx_lowest где значение истинно

val trueIndexes = idx_lowest .zipWithIndex filter(x => x._1  ) map(_._2)
trueIndexes: Array[Int] = Array(0, 5)

Найти значения по trueIndexes в исходном массиве.

val tmp = trueIndexes map original
Array[Double] = Array(3.0, 6.0)

Выполнить операция над элементами массива tmp .

val tmp1 = tmp  map (x => (x+lower)/2.0)
Array[Double] = Array(16.5, 18.0)

Обновить элементы массива solution . Индексы указаны как trueIndexes . Элементы, размер которых меньше нижнего , обновляются.

for(i <- tmp1.indices)  {
    solution(trueIndexes(i)) = tmp1(i)
  }

Обновленный массив решений:

Array[Double] = Array(16.5, 33.0, 31.0, 82.0, 51.0, 18.0, 39.0, 96.0, 95.0, 49.0)

Те же шаги должны быть выполнены для обновления элементов, которые больше верхней границы. Вот код.

val idx_false : Array[Boolean]  = solution.map ( x => x > upper )
val falseIndexes = idx_false .zipWithIndex filter(x => x._1  ) map(_._2)
val tmp2 = falseIndexes map original 
val tmp3 = tmp2 map (x => (x+upper)/2.0)
for(i <- tmp3.indices)  {
   solution(falseIndexes(i)) = tmp3(i)
}
solution

Этот код делает именно то, что мне нужно, но для выполнения множества операций. В итеративном алгоритме я должен выполнять эти операции на каждой итерации для каждого массива. Есть ли более эффективный, оптимальный и быстрый способ выполнить ту же операцию?

Ответы [ 2 ]

4 голосов
/ 07 августа 2020

Вы можете zip их и сопоставить за одну операцию:

solution.zip(original)
  .map { case(s, o) => if(s < lower) ((o + lower) / 2, o) else (s, o) }
  .map { case(s, o) => if(s > upper) (o + upper) / 2 else s }
3 голосов
/ 07 августа 2020

Разве это не тот же результат?

val done = solution.indices.map{x =>
  if (solution(x) < lower)      (lower + original(x))/2.0
  else if (solution(x) > upper) (upper + original(x))/2.0
  else solution(x)
}.toArray
...