Массив Scala без имени

Вот как я могу проверить, является ли число четным / нечетным в Ruby:

def even_or_odd(number)
  ['Even', 'Odd'][number % 2]
end

Ближайшее, что у меня есть в Scala, это следующее:

  def evenOrOdd(number: Int): String = {
     val a = Array("Even", "Odd")
     a(number % 2)
  }

Я действительно хочу сделать что-то вроде этого, но он не компилируется:

  def evenOrOdd(number: Int): String = {
    ("Even", "Odd")(number % 2)
  }

Во-первых, как называется этот тип «анонимной» структуры? Во-вторых, как это элегантно использовать? Если у вас есть аналогичный пример, иллюстрирующий мощь / лаконичность / ясность Scala, я бы хотел его увидеть.

Что ж ... такие варианты использования никоим образом не показывают «мощь» языка. И conciseness, и clarity очень субъективны к пользователю. Сила Scala заключается в ее системе типов и функциональных возможностях.

sarveshseri 15.11.2018 13:13

Я понимаю. Это тривиальный пример, подчеркивающий мою проблему. Я планирую использовать эту конструкцию там, где в плохо написанных программах есть несколько операторов if-then, перемежающихся литералами. В моем бизнесе краткость и ясность имеют прямое влияние на прибыльность. Философ может справедливо возразить, что они субъективны, но красота в глазах смотрящего, и мои коллеги на нее проницательны.

Fred 15.11.2018 14:52

Языки программирования - это инструменты. Вы можете думать о них как о различных видах транспорта. У вас есть велосипеды, автомобили, автобусы, грузовики, трейлеры, поезда, телеги, лошади. Каждый из них может привести вас в разные места, но отличается друг от друга, и у каждого есть свои сильные и слабые стороны. Сейчас эстетики сильно отличаются друг от друга. conciseness и clarity - это хорошо, но я каждый раз буду выбирать correctness над ними обоими.

sarveshseri 15.11.2018 17:03

Это взлом. Более того, он выдаст ошибку при отрицательных нечетных числах, поскольку -1 % 2 оценивается как -1 в Scala, Java, JavaScript и, возможно, в некоторых других. Просто используйте if (number % 2 == 0) "even" else "odd". Легче читать и работает.

Brian McCutchon 15.11.2018 19:40

Брайан, если вы хотите увидеть оригинальный хак, взгляните на это: stackoverflow.com/questions/51126534/fizzbuzz-ruby-one-liner. Руби умеет работать с отрицательными индексами. Это может быть полезно с индексами, основанными на расчетах. К сожалению, Scala и Java не делают отрицательных индексов. На мой взгляд, это слабость.

Fred 15.11.2018 20:42
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
5
83
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это компилирует:

def evenOrOdd(number: Int): String = {
    Array("Even", "Odd").apply(number % 2)
}

В большинстве случаев вызов метода apply можно опустить, поскольку он имеет синтаксический сахар. Однако в этом случае это не сработает. Вам нужно либо извлечь Array("Even", "Odd") в var, var или def, либо отказаться от синтаксического сахара.

Причину, по которой синтаксический сахар Array("Even", "Odd")(number % 2) не работает, как-то сложно объяснить, но это вызвано следующим:

  • Java не позволяет создавать универсальные массивы (например, new T[], где T - универсальный тип)
  • Scala позволяет создавать универсальные массивы, используя ClassTag в Array.apply; ClassTag поставляется со своим собственным синтаксическим сахаром, что делает Array("Even", "Odd")(number % 2) недействительным.

("Even", "Odd") относится к типу (String,String), который является псевдонимом для Tuple2[String, String], его вспомогательными устройствами являются ._1 и ._2.

ты мог бы сделать Array("Even", "Odd")(number % 2) или Обновлено: как указано в комментариях, это на самом деле не сработает. Это будет, хотя Array("Even", "Odd").apply(number % 2)

number % 2 match {
    case 0 => "Even"
    case 1 => "Odd"
    case -1 => "Odd" //EDIT: as per comment. I forgot about this case
}
Array("Even", "Odd")(number % 2) не компилируется. Это как-то связано с параметром типа ClassTag, но я не могу предоставить более подробную информацию по этому поводу.
ygor 15.11.2018 13:07

да ты правый странный. например Array(1,2)(4 % 2) работает как положено Подредактирую. Благодарность!

Dominic Egger 15.11.2018 13:11
Vector("Even", "Odd")(number % 2) компилируется.
Lasf 15.11.2018 19:37

Ваш пример не работает с отрицательными числами. Вам, вероятно, следует изменить второй регистр на _

Ethan 16.11.2018 23:19
Ответ принят как подходящий
def evenOrOdd(number: Int) = 
 List("Even","Odd")(number % 2)

Другие вопросы по теме