代码之家  ›  专栏  ›  技术社区  ›  Mladen Jablanović

使用并行分配交换数组元素

  •  4
  • Mladen Jablanović  · 技术社区  · 14 年前

    被吸引 this question ,我对数组和方法调用的并行赋值做了一些尝试。下面是一个范例,试图根据数组中的两个成员的值交换它们:

    deck = ['A', 'B', 'C']
    #=> ["A", "B", "C"]
    deck[deck.index("A")], deck[deck.index("B")] = deck[deck.index("B")], deck[deck.index("A")]
    #=> ["B", "A"]
    deck
    #=> ["A", "B", "C"]
    

    数组没有改变。但如果我们改变争论的顺序,它就会起作用:

    deck[deck.index("B")], deck[deck.index("A")] = deck[deck.index("A")], deck[deck.index("B")]
    #=> ["A", "B"]
    deck
    #=> ["B", "A", "C"]
    

    我想这和打电话给 index 方法,但看不清楚。有人能解释一下下面的顺序吗?为什么第一个例子不交换成员,第二个例子不交换成员?

    3 回复  |  直到 7 年前
        1
  •  3
  •   user507577user507577    14 年前

    这是意料之中的。它遵循ruby计算表达式的方式。

    deck[deck.index("A")], deck[deck.index("B")] = deck[deck.index("B")], deck[deck.index("A")]
    

    暗示

    deck[deck.index("A")], deck[deck.index("B")] = 'B', 'A'
    

    注意:这里的字符串“A”和“B”仅供说明。Ruby不会在这里创建新的字符串对象 . 本质上是:

    deck[deck.index("A")] = 'B' -> deck[0] = 'B' (deck = ['B', 'B', 'C'])
    deck[deck.index("B")] = 'A' -> deck[0] = 'A' (deck = ['A', 'B', 'C'])
    

    数组索引在找到第一个匹配项时返回。

    现在,

    deck[deck.index("B")], deck[deck.index("A")] = deck[deck.index("A")], deck[deck.index("B")]
    -> deck[deck.index("B")], deck[deck.index("A")] = 'A', 'B'
    -> deck[deck.index("B")] = 'A' -> deck[1] = 'A' (deck = ['A', 'A', 'C'])
    -> deck[deck.index("A")] = 'B' -> deck[0] = 'B' (deck = ['B', 'A', 'C'])
    
        2
  •  1
  •   the Tin Man    14 年前

    就像一个例子,比较用于搜索数组的机器,找到正确的索引,然后交换值,使用散列可以执行的操作:

    h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
    
    h['dog'], h['cat'] = h.values_at('cat', 'dog')
    
    h #=> {"cat"=>"canine", "dog"=>"feline", "cow"=>"bovine"}
    

    如果鲁比有一个 values_at= 散列方法它甚至可以更干净:

    h.values_at('dog', 'cat') = h.values_at('cat', 'dog')
    

    但是,唉,我们没有。Hash切片在Perl中是一个非常强大的工具,我也很怀念Ruby。

    是的,我知道我可以加上我自己的 价值观= .

        3
  •  1
  •   Andrew Grimm atk    14 年前

    拉杰什先生是对的,但他必须思考才能解决问题。我太懒了!

    这里有一个printf调试方法来显示发生了什么。

    deck = ['A', 'B', 'C']
    #=> ["A", "B", "C"]
    deck[deck.index("A").tap {|index| 
      STDERR.puts "Result of indexing for #{"A".inspect} is #{index.inspect}"
      }], 
    deck[deck.index("B").tap {|index| 
      STDERR.puts "Result of indexing for #{"B".inspect} is #{index.inspect}"
      }] = 
    deck[deck.index("B")], deck[deck.index("A")]
    # Result of indexing for "A" is 0
    # Result of indexing for "B" is 0
    #=> ["B", "A"]
    deck
    #=> ["A", "B", "C"]