Какова Ваша любимая функция в Ruby? [закрытый]

Вот способ:

//Construct dataframe
val df = sc.parallelize(Seq((1,"{\"name\":\"Anne\",\"Age\":\"12\",\"country\":\"Denmark\"}"), 
             (2, "{\"name\":\"Zen\",\"Age\":\"24\"}"), 
             (3, "{\"name\":\"Fred\",\"Age\":\"20\",\"country\":\"France\"}"), 
             (4, "{\"name\":\"Mona\",\"Age\":\"18\",\"country\":\"Denmark\"}"))).toDF("ID", "details_Json")

df.show

+---+--------------------+
| ID|        details_Json|
+---+--------------------+
|  1|{"name":"Anne","A...|
|  2|{"name":"Zen","Ag...|
|  3|{"name":"Fred","A...|
|  4|{"name":"Mona","A...|
+---+--------------------+

import org.apache.spark.sql.types.{StructType, StructField, StringType, IntegerType}
val struct =
  StructType(
    StructField("name", StringType, true) ::
    StructField("Age", StringType, true) ::
    StructField("country", StringType, true) :: Nil)
val df2 = df.withColumn("details_Struct", from_json($"details_Json", struct)).withColumn("country", $"details_Struct".getField("country")).filter($"country".equalTo("Denmark")).drop("country", "details_Struct")

df2.show
+---+--------------------+
| ID|        details_Json|
+---+--------------------+
|  1|{"name":"Anne","A...|
|  4|{"name":"Mona","A...|
+---+--------------------+

Ответ выше в Apache Spark 2.3.1. Какую версию вы используете? В версии 2.4.1 есть функция schema_of_json, которая автоматически выводит схему. Вы можете также проверить это. https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.functions$@schema_of_json (JSON: String): org.apache.spark.sql .Column

6
задан Community 23 May 2017 в 12:26
поделиться

13 ответов

Блоки действительно хороши:

my_array.each { |element| print element } 

#...

File.open("foo.txt") do |file|
  # do stuff with file
end
12
ответ дан 8 December 2019 в 02:22
поделиться

Это - довольно маленькая, почти незначительная функция, но мне действительно нравится эта конструкция:

var ||= "default"

Это устанавливает var к значению по умолчанию ("default") если var еще не был установлен или сохраняет текущее значение var если это уже было установлено. Мне нравится компактный синтаксис.

В том же направлении я могу сделать что-то вроде этого:

new_val = old_val || "default"

установить значение по умолчанию, также.

В целом мне нравится, как все выражения Ruby возвращают значение, таким образом, я могу использовать операторы как || записать короткие, компактные операторы.

7
ответ дан 8 December 2019 в 02:22
поделиться

Мне нравится способность вызвать функции без круглых скобок и функции, возвращая последнее оцененное выражение.

Первый сохраняет много ненужных круглых скобок и делает код легче читать.

Последний может стать довольно сбивающим с толку иногда, но это является большим для короткого (особенно логичный) функции.

3
ответ дан 8 December 2019 в 02:22
поделиться

Счетный! Некоторые примеры того, почему это является потрясающим.

a = ['foo', 'bar', 'baz']

a.delete_if {|i| i =~ /^f/ }
# vs
new = []
a.each do |i|
  if i !~ /^f/
    new << i
  end
end



a.select {|i| i =~ /^f/ }
# vs
new = []
a.each do |i|
  if i =~ /^f/
    new << i
  end
end


a.detect {|i| i =~ /^f/ }
# vs
a.each do |i|
  if i =~ /^f/
    return i
  end
end

Очень хорошо смочь сказать непосредственно, чего Вы хотите достигнуть с 'выбором', 'обнаружьте', 'delete_if' и так далее, вместо цикличного выполнения и выполнения всего вручную. Счетный помогает ввести, и легче понять при чтении кода.

3
ответ дан 8 December 2019 в 02:22
поделиться

То, что классы являются объектами, и новый метод на классе:

c = Array
a = c.new()

И мне нравится как патронажные работы. Это называет === на каждом значении случая и возвращает значение:

if(0 <= age &&  age <= 10){
  x = "kid"
}else if(10 <= age && age <= 80)
  x = "person"
}else if(80 <= age && age <= 99)
  x = "old"
}else{
  x = "???"
}

=>

x = case age
  when 0..10:  "kid"
  when 10..80: "person"
  when 80..99: "old"
  default:     "???"
end

Это работает потому что диапазоны (0.. 10), имеют === метод, который проверяет, находится ли что-то в диапазоне: (5.. 10) === 6 ==> верный. Regexes поддерживают === также, таким образом, можно сделать:

case str
  when /regex1/: ...
  when /regex2/: ...
  ...
end

Можно даже записать === метод для собственных объектов.

2
ответ дан 8 December 2019 в 02:22
поделиться

Другая хорошая функция: удостовериться. Это похоже наконец, но имеет краткий синтаксис в Ruby. Можно использовать его, когда у Вас есть что-то вроде этого:

def foo(x)
  return_value = bar(x)
  dosomething(x)
  return return_value
end

=>    

def foo(x)
  bar(x)
ensure
  dosomething(x)
end
2
ответ дан 8 December 2019 в 02:22
поделиться

вопросительный знак / соглашение о присвоении имен восклицательного знака

часто никакой parens, необходимый после вызова метода

закрытия

rubygems

Хорошо, я предполагаю, что это - некоторые избранное :)

1
ответ дан 8 December 2019 в 02:22
поделиться

Моей любимой функцией прямо сейчас (после контакта с Soap4R недавно) является, вероятно, самоанализ, это доступно. Эти два метода особенно полезны:

public_methods - Возвращает список всех методов на объекте. Супер полезный от отладчика или irb, когда Вы пытаетесь выяснить то, что можно сделать к чему-то. (Второй

instance_variables - Возвращает список всех переменных экземпляра на объекте.

Существуют все виды другого хорошего материала здесь: http://www.ruby-doc.org/core/classes/Object.html

1
ответ дан 8 December 2019 в 02:22
поделиться

Открытые классы являются одним из моего избранного. Например, это:

# try.rb

class TryObjectMock
  public_instance_methods.reject { |x| x =~ /^__/ }.each { |x| undef_method(x) }

  def method_missing(symbol, *args)

  end
end

class Object
  def try
    self.nil? ? TryObjectMock.new : self 
  end
end

делает код, который обрабатывает nilспособные более ясные объекты:

irb(main):001:0> require 'try'
irb(main):002:0> puts "5".try.to_i
5
irb(main):003:0> puts nil.try.to_i
nil
irb(main):004:0> puts [1, 2].try.find { |x| x == 2 }.try + 3
5
irb(main):005:0> puts [1, 2].try.find { |x| x == 3 }.try + 3
nil
irb(main):006:0> puts nil.try.find { |x| x == 3 }.try + 3
nil
irb(main):007:0>

Это избегает большого количества из if-elses:

irb(main):007:0> a = [1, 2]
irb(main):008:0> puts(if a
irb(main):009:2>        if b = a.find { |x| x == 2 }
irb(main):010:3>          b + 3
irb(main):011:3>        end
irb(main):012:2>      end)
5
irb(main):013:0> c = "5"
irb(main):014:0> puts(c ? c.to_i : nil)
5

Прием работает путем определения метода try для каждого класса в объектном пространстве. Когда это звонило, это возвращает специальный объект, когда объект nil (nil экземпляр NilClass, который является подклассом Object!) или сам объект иначе. Тот специальный объект просто возвращается nil для каждого названного метода (через пустое method_missing реализация). Обратите внимание, что это также работает на операторы, так как они - методы объекта левой стороны.

2
ответ дан 8 December 2019 в 02:22
поделиться

instance_eval и class_eval :)

1
ответ дан 8 December 2019 в 02:22
поделиться

Операторы if также являются выражениями, поэтому последняя строка блока возвращает значение. Допускается код вроде:

my_var = if some_var.is_true?
           if some_other_var > 8
             1
           else
             23
           end
         else
           5
         end

Здесь my_var будет иметь значение 1, 23 или 5, в зависимости от того, как оцениваются условия.

1
ответ дан 8 December 2019 в 02:22
поделиться

Логические операторы для не логических значений.

&& и ||

Оба возвращают значение последнего вычисленного выражения. Благодаря короткому замыканию они создают удобные короткие пути. Они рассматривают любое значение, отличное от nil или false, как истинное для целей обнаружения короткого замыкания.

Пример:

a = b || c 

Присваивает значение c переменной a, только если b равно нулю или false.

a = b && c

Присваивает значение of c для a, только b не является nil или false, в противном случае присваивается b.

Такое поведение объясняет уже упомянутый || = .

Однако оператор && = не получает такой же любви.

string &&= string + "suffix"

эквивалентно

if string
  string = string + "suffix"
end

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

2
ответ дан 8 December 2019 в 02:22
поделиться

Я не мог выбрать только один, но первое, что пришло в голову, было splat: *

По сути, он позволяет вам превращать массив в список аргументов и наоборот , позволяя делать такие вещи:

odds  = [1, 3, 7]
evens = [2, 4, 6]

case 4
  when *odds  then "odd!"
  when *evens then "even!"
end
# => "even!"


arr = [ :a, 1, :b, :2 ]    
Hash[*arr] # => { :a => 1, :b => 2 }


a, b, c = *(1..3)
puts a # => 1
puts b # => 2
puts c # => 3


a = 1, *[2, 3] # => [1, 2, 3]


# And of course...
def f(*args)
  puts args
end

f 1, 2, 3 # => [1, 2, 3]
2
ответ дан 8 December 2019 в 02:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: