【问题标题】:Array destructuring in RubyRuby 中的数组解构
【发布时间】:2021-10-23 16:44:27
【问题描述】:

我有一个变量data,它采用以下两种格式之一:

  1. [1,2,3]
  2. [[1,2,3],['a','b','c']]

在某些时候我需要解析这些数据,所以我这样做了:

main, alternative = data

虽然情况 (2) 可以按预期工作,但 (1) 不能。 相反,它设置:

main=1 
alternative=2 
# 3 is dropped.

我的最终目标是:

main=[1,2,3] 
alternative=nil 

最优雅的方法是什么?理想情况下,我想避免使用条件和长方法...

【问题讨论】:

  • 我想给你一个条件,因为它更容易理解发生了什么,这使得代码在未来更容易阅读和维护。

标签: arrays ruby-on-rails ruby multidimensional-array


【解决方案1】:

我在这里诚实的回答是不要在模糊、定义不明确的结构中传递数据。如果可能,请改进底层调用者以发送一致定义的对象。

但是,如果您正在寻找快速补丁,那么如何:

# data comes in one of the following two formats:
# 1. [1,2,3]
# 2. [[1,2,3],['a','b','c']]
# So, this patch enforces some consistency in the structure:
data = [data, nil] unless data.first.is_a?(Array)

main, alternative = data

【讨论】:

  • 你完全正确。然而在这一点上,结构是我无法控制的。您的解决方案似乎可以解决问题..Thnx!
  • 由于 Ruby 是一种鸭子类型语言,您可能想要检查是否可以将某些内容视为数组 (to_ary) 而不是检查类。 data.first.respond_to?(:to_ary) 这并不一定比检查课程更好或更差,而只是一个偏好问题。
【解决方案2】:

如果你有幸在 ruby​​ 2.7 或 3 上运行,你可以使用模式匹配:

case data
in [Array => main, Array => alternative]
  # here `main` and `alternative` are bound to the expected items
  # because the match succeeds by type.
in main
  # now main is bound but alternative might still be bound to the previous
  # clause, so don't use it.
  alternative = nil
end

一种更流畅但仍然正确的方式是

data in [Array => main, Array => alternative] or data in Array => main

# now main and alternative are as expected

如果事先知道数组的结构(长度)为 3,您可能也会感到满意

data in [[_,_,_] => main, [_,_,_] => alternative] or data in [_,_,_] => main

所以你有更少的假阴性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多