Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby에서 splats를 사용하여 배열 구축 및 분리

내가 Ruby를 좋아하는 이유 중 하나는 기능의 깊이입니다. 연산자를 사용할 수는 있지만 조금만 파고들어보면 연산자가 할 수 있는 것의 표면만 긁고 있다는 것을 알게 될 것입니다. 겸손한 표시 연산자(*** )가 좋은 예입니다.

"catch-all" 인수에 대해 splats를 사용했을 것입니다. 그리고 그것이 대부분의 사람들이 사용하는 전부입니다.

def go(x, *args)
  puts args.inspect
end

go("a", "b", "c")

newfangled 키워드 인수 구문을 사용하는 경우 다음과 같이 이중 표시를 사용하십시오.

def go(**params)
  puts params.inspect
end

go(x: 100, y: 200)

이것은 유용하지만 더 많은 용도로 splats를 사용할 수 있습니다. 뛰어들자!

배열을 사용하여 여러 인수 전달

메서드를 정의할 때 splat을 사용할 수 있을 뿐만 아니라 메서드를 호출할 때도 사용할 수 있습니다. 여러 인수를 예상하는 함수에 배열을 전달할 수 있습니다. 배열의 첫 번째 항목이 첫 번째 인수가 되고 두 번째 항목이 두 번째 인수가 되는 식입니다.

def go(x, y)
end

point = [12, 10]
go(*point)

그리고 새로운 스타일의 키워드 인수에 이중 표시를 사용할 수 있음을 잊지 마십시오.

def go(x:, y:)
end

point = { x: 100, y: 200 }
go(**point)

표시는 끝에 갈 필요가 없습니다

주장 목록의 끝에 튀긴 주장을 넣는 것이 일반적이지만 이를 요구하는 법률은 없습니다.

인수 목록의 아무 곳에나 표시를 넣을 수 있습니다.

def go(x, *args, y)
  puts x # => 1
  puts y # => 5
  puts args.inspect # => [2,3,4]
end

go(1, 2, 3, 4, 5)

배열 분해

인수가 있는 이러한 모든 트릭은 배열 구조 분해의 특별한 경우일 뿐입니다.

"배열 구조 분해"라는 용어에 익숙하지 않은 경우 단순히 배열을 개별 항목으로 나누는 것을 의미합니다. 다음과 같습니다.

a, b = [1, 2]
puts a
# 1
puts b
# 2

이것은 잘 작동하지만 배열의 모든 단일 항목을 보유하기 위해 변수를 지정해야 하는 것은 고통스러울 수 있습니다. splat 연산자는 이 문제를 해결합니다. 본질적으로 와일드카드처럼 작동합니다. 몇 가지 예를 살펴보겠습니다.

배열에서 첫 번째 항목 팝핑

때때로 원래 배열을 변경하지 않고 배열에서 첫 번째 항목을 팝할 수 있는 것이 유용합니다. 이것이 바로 이 예가 하는 일입니다.

first, *remainder = [1, 2, 3, 4, 5]
first
# => 1
remainder
# => [2, 3, 4, 5]

첫 번째 항목만 원하고 나머지 배열은 원하지 않는 경우 다음 구문을 사용할 수 있습니다.

first, * = [1, 2, 3, 4, 5]
first
# => 1

마지막 항목 팝핑

시작 대신 배열의 끝에서 항목을 빼내려면 다음과 같이 시작 부분에 표시를 붙이십시오.

*prefix, last = [1, 2, 3, 4, 5]
last
# => 5
prefix
# => [1, 2, 3, 4]

다시 말하지만 특정 변수를 원하지 않으면 할당할 필요가 없습니다.

배열의 처음 및 마지막 n개 항목 가져오기

splat 연산자를 중간에 넣으면 배열의 각 끝에서 임의의 수의 항목을 가져올 수 있습니다.

first, *, last =  [1, 2, 3, 4, 5]
first
# => 1
last
# => 5

제한 사항

배열 구조화에서 splat 연산자를 사용할 때 여전히 배열의 시작과 끝을 기준으로 배열 항목의 위치를 ​​지정해야 합니다. 따라서 긴 배열의 중간에서 항목을 추출하는 데 가장 좋은 도구는 아닙니다.

또한 이중 표시(** ) 연산자를 사용하여 해시를 엉망으로 만듭니다. 절름발이!

배열 구성

splat 연산자는 배열을 구조화할 때뿐만 아니라 배열을 구성하는 데에도 유용합니다.

다음 예에서는 splat을 사용하여 두 배열을 결합합니다.

[*[1,2], *[3,4]]
=> [1, 2, 3, 4]

이는 [[1, 2], [3,4]].flatten과 동일합니다. .

그것이 이야기의 끝이라면 그것은 별로 유용하지 않을 것입니다. 그러나 splat에는 또 다른 독특한 능력이 있습니다. 지능적으로 객체를 배열로 강제 변환할 수 있습니다.

# Usually `*thing` wraps `thing` in an array
x = *"hi mom"
# => ["hi mom"]

# ...unless it's nil
x = *nil
# => []

# Arrays are passed through unchanged
x = *[1,2,3]
# => [1, 2, 3]

# But hashes are converted to arrays
x = *{a: 1}
# => [[:a, 1]]

이것은 우리에게 많은 수동 유형 강제를 수행하지 않고도 배열을 구축할 수 있는 도구를 제공합니다.

예를 들어, 일부 구성 시스템에 대한 문자열 배열을 수집한다고 상상해 보십시오. 일반적으로 다음을 원할 것입니다.

  • 배열이 있는지 확인하고 없으면 초기화
  • 누군가가 단일 문자열이 아닌 문자열 배열을 추가하려고 하면 지능적으로 대응

splat 연산자는 우리에게 이것을 무료로 제공합니다:

# Your configuration hash may or may not have
# an existing :ignore array. 
config = { }

# The callback function might return an array
# or it might return a single item. 

def add_ignores
  "scoundrels" # could also be an array like ["scoundrels", "cads", "ne'er-do-wells"]
end

# This is where the magic happens. No matter what you 
# start with you get an array of things to ignore. 
config[:ignore] = [*config[:ignore], *add_ignores()]

그게 다야

스플랫을 사용하기 위해 기존 배열 조작 코드를 모두 다시 작성해서는 안 된다는 것이 분명하기를 바랍니다. 항상 올바른 도구는 아니며 자주 사용하면 코드를 읽기 어렵게 만들 수 있습니다.

그러나 때때로 어레이 스플랫 트릭이 정확히 필요한 것입니다. 그때가 되면 한 번 시도해 보시길 바랍니다. :)