Извлечение элементов из списка

var x:List[Any]=List(3, List('a, 'b, 'c, 'd, 'f, 'g, 'h))
def LoopRandS(c:Int):Unit= {
  var n: Int = 0
  val y: List[Symbol] = List('a, 'b, 'c, 'd, 'f, 'g, 'h)
  var list = List[Symbol]()
  if (c <= 0 || y.isEmpty ) print(y)
  else for(i<-1 to y.size) {
    for(m<-y){
      val R=Random.between(1,y.size)
      if(n==R) list=list.::(m)
      n+=1
    }
  }
  print(list)
}

Мне надо извлечь из данного списка заданное количество случайно выбранных элементов.Я че то вообще не понимаю,как это сделать адекватно,ерунду какую-то написал.Использовать можно только Random,остальное все писать руками,без функций по типу random.shuffle. Результат должен быть по типу такого res0: List[Symbol] = List('e, 'd, 'a)


Ответы (1 шт):

Автор решения: Ким Денис
import scala.util.Random

val list: List[Symbol] = List('a, 'b, 'c, 'd, 'f, 'g, 'h)

@annotation.tailrec
def randomElements(n: Int, available: List[Int], acc: List[Symbol]): List[Symbol] =
  if (n != 0) {
    val index = available(Random.between(0, available.size))
    randomElements(n - 1, available.filterNot(_ == index), list(index) :: acc)
  else {
    acc
  }

println(randomElements(3, list.indices.toList, List.empty[Symbol]))

Хвостовая рекурсия.
list - заданный лист элементов.
n - количество элементов для извлечения.
acc - хранит случайно извлеченные элементы.
available - во избежании повторного получения одного и того же элемента, хранит не использованные индексы.

Объяснение: Функция работает пока n не достинет нуля. Если n не равен нулю, то получаем случайный доступный индекс из списка available, по этому индексу получаем элемент из list и добавляем в acc.

Уменьшаем n, исключаем использованный индекс из available, передаём новые данные рекурсивной функции.

→ Ссылка