заставьте объект вести себя как Массив для параллельного присвоения в рубине

Вы можете указать индекс массива. В этом случае 27-й в массиве является индексом 26.

const result = {
  resource: "playerdashboardbygeneralsplits",
  parameters: {},
  resultSets: [{
      name: "OverallPlayerDashboard",
      headers: [],
      rowSet: [
        [
          "Overall",
          "2018-19",
          60,
          37,
          23,
          0.617,
          2247.0583333333334,
          651,
          1483,
          0.439,
          294,
          809,
          0.363,
          603,
          687,
          0.878,
          55,
          334,
          389,
          451,
          314,
          130,
          45,
          91,
          196,
          452,
          2199,
          119,
          3553.3,
          23,
          6,
          1,
          1
        ]
      ]
    },
    {},
    {},
    {},
    {},
    {},
    {}
  ]
}
console.log(result.resultSets[0].rowSet[0][26])

5
задан allyourcode 20 April 2009 в 02:53
поделиться

3 ответа

Yep. Define #to_ary. This will let your object be treated as an array for assignment.

irb> o = Object.new
=> #<Object:0x3556ec>
irb> def o.to_ary
       [1, 2]
     end
=> nil
irb> x, y = o
=> [1,2]
irb> x
#=> 1
irb> y
#=> 2

The difference between #to_a and #to_ary is that #to_a is used to try to convert a given object to an array, while #to_ary is available if we can treat the given object as an array. It's a subtle difference.

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

Вы не можете переопределить присваивание, потому что это оператор, а не метод. Но если ваш класс AllYourCode наследуется от Array, ваш пример будет работать.

Когда Ruby встречает назначение, он смотрит на правую сторону и, если существует более одного значения, собирает их в массив. Затем он смотрит на левую сторону. Если там есть одно значение lvalue, ему присваивается массив.

def foo 
  return "a", "b", "c" # three rvalues
end

x = foo # => x == ["a", "b", "c"]

Если имеется более одного значения lvalue (точнее, если он видит запятую), он последовательно назначает значения r и отбрасывает дополнительные.

x, y, z = foo # => x == "a", y == "b", z == "c"
x, y = foo    # => x == "a", y == "b"
x, = foo      # => x == "a"

Вы можете сделать параллельное присваивание, если массив также возвращается, как вы обнаружили.

def bar
  ["a", "b", "c"]
end

x = bar       # => x == ["a", "b", "c"]
x, y, z = bar # => x == "a", y == "b", z == "c"
x, y = bar    # => x == "a", y == "b"
x, = bar      # => x == "a"

Итак, в вашем примере, если rb является массивом или наследует от массива, x и y будут назначены его первые 2 значения.

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

Почти:

class AllYourCode
   def to_a
     [1,2]
   end
end

rb = AllYourCode.new
x, y = *rb
p x
p y

Splat попытается вызвать to_ary , а затем попытается вызвать to_a . Я не уверен, почему вы хотите сделать это, хотя это действительно синтаксическая функция, которая использует Array в своей реализации, а не функцию Array .

Другими словами, варианты использования для множественного назначения - это такие вещи, как:

# swap
x, y = y, x

# multiple return values
quot, rem = a.divmod(b)

# etc.
name, age = "Person", 100

Другими словами, большую часть времени объект, от которого назначается (массив ), даже не очевиден.

2
ответ дан 13 December 2019 в 22:16
поделиться
Другие вопросы по тегам:

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