Перевод кода с Ruby на Scala - PullRequest
0 голосов
/ 13 мая 2018

Я конвертирую некоторый код из Ruby в Scala.Проблема в том, что я никогда не программировал Ruby в своей жизни.Все идет хорошо, но теперь я достиг двух строк, которые я не понимаю.Как я могу преобразовать последние 2 строки Ruby в Scala?

  num_obs = pop.first[:objectives].size
  num_obs.times do |i|
    min = pop.min{|x,y| x[:objectives][i]<=>y[:objectives][i]}
    max = pop.max{|x,y| x[:objectives][i]<=>y[:objectives][i]}
    /* do sth. with min and max */
  end

pop is Vector [Map [String, Any]]

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

Другой ответ хорош, но я считаю, что код может быть намного проще.Код на Ruby довольно плохой (не только это, он даже синтаксически незаконен!), И я бы вообще не пытался его переводить, вероятно, было бы гораздо лучше переписать его, чем переводить.

Две конкретные строки, о которых вы спрашиваете, являются просто очень запутанным способом записи

min, max = pop.minmax_by { |x| x[:objectives][i] }

Однако, поскольку min и max являются локальными переменными блока, они сразу выходят из области видимости вконец блока, и поскольку они больше нигде не используются, весь цикл фактически не используется.(Если Enumerable#min или Enumerable#max или Hash#[] / Array#[] не будут переопределены, чтобы иметь некоторый побочный эффект, который был бы действительно странным.)

Integer#times оценивается как self, так что все это фактически эквивалентно:

pop.first[:objectives].size

Эквивалент Scala, равный

pop.head('objectives).size

Но на самом деле ,Размещенный вами код Ruby синтаксически недопустим, так что на самом деле это не код Ruby вообще , и нет эквивалента Scala.

0 голосов
/ 13 мая 2018

Кажется, что все |x,y| f(x) <=> f(y) просто сравнивает x и y по некоторому свойству f, а <=> возвращает -1, 0, 1. То же самое можно выразить гораздо проще, если вместо предоставления compare метода с возвращаемыми значениями -1, 0, 1 мы просто сравним f. В Scala это будет что-то вроде:

val pop: Vector[Map[String, Any]] = ???
val num_obs: Int = ???
for (i <- 0 until num_obs) {
  val min = pop.minBy(_("objectives").asInstanceOf[Vector[Int]](i))
  val max = pop.maxBy(_("objectives").asInstanceOf[Vector[Int]](i))
  /* do sth. with min and max */
}

Обратите внимание, что я заменил символы :objectives на String, хотя Scala также имеет тип Symbol (соответствующий символ будет 'objectives). Я также предположил, что значения на карте - это что-то вроде векторов целых чисел (в противном случае индексация с помощью i не имеет никакого смысла).

...