将数组中的 x 元素移动到末尾。

9

我正在尝试找到一种方法,将特定的关系移动到数组的末尾。基本上,我有一个current_account,我想把这个账户移到账户关系数组的末尾,以便在迭代关系时最后显示。如果可能的话,我想创建一个作用域并使用SQL,以下是我的尝试,但我还没有真正取得任何进展。

HTML

<% current_user.accounts.current_sort(current_account).each do |account| %>
   <li><%= link_to account.name, switch_account_accounts_path(account_id: account.id) %></li>
<% end %>

这段代码返回了一个按照创建时间排序的账户列表。我不想按照创建时间排序,而是想让current_account排在最后,所以我创建了一个名为current_sort的作用域,但是我不确定该怎么做。

账户上的CURRENT_SORT作用域

 scope :current_sort, lambda { |account|

 }

我希望这个作用域在关联数组中返回传入的账户最后一个。我该如何使用SQL或Ruby实现?


2
为什么不直接使用 sort_by { |v| v == current_account ? 1 : 0 } 呢? - tadman
@tadman 非常好!没有理由不这样做。 - Bitwise
你也可以使用 list - [ current_account ] + [ current_account ],但这看起来更加混乱。 - tadman
是的,不过那是一个有趣的观点。 - Bitwise
2个回答

9

将数组中特定元素排在末尾的快捷方法是:

array.sort_by { |v| v == current_account ? 1 : 0 }

如果您想移动多个元素,可以更轻松地完成:

to_end = [ a, b ]

array - to_end + to_end

编辑:正如Stefan所指出的,这可能会重新排序项目。为了解决这个问题:

array.sort_by.with_index do |v, i|
  v == current_account ? (array.length + i) : i
end

您也可以使用不同的方法来处理它,使用partition方法:

array.partition { |v| v != current_account }.reduce(:+)

这是一种与 Stefan 的回答中使用的方法略有不同的变体。

1
太好了。请注意,array - to_end + to_end 只能像集合一样运作。[1,1,1,1,1,2]-[1]==[2] - dawg
1
Ruby的sort/sort_by不是稳定的。你的解决方案将current_account放在最后,但它可能会无意中重新排序其余项目。这可以通过考虑每个项目的索引来解决,即:array.sort_by.with_index { |v, i | [v == current_account ? 1 : 0, i] } - Stefan
@Stefan 那是个好观点。我已经添加了另外两种方法来解决这个问题,其中一种显然你已经提到了,现在我已经检查过了。 - tadman
为什么你使用(array.length + i) : i而不是1 : 0?在后面有, i的情况下似乎有些多余,但也许我漏掉了什么。 - Stefan
@Stefan 啊,我明白你在那个数组中使用第二排序因素的意思了。 - tadman

5
您可以使用 partition 按条件分割数组。
array = [1, 2, 3, 4, 5, 6, 7, 8]
current_account = 3

other_accounts, current_accounts = array.partition { |v| v != current_account }
#=> [[1, 2, 4, 5, 6, 7, 8], [3]]

other_accounts
#=> [1, 2, 4, 5, 6, 7, 8]

current_accounts
#=> [3]

结果可以连接起来:
other_accounts + current_accounts
#=> [1, 2, 4, 5, 6, 7, 8, 3]

或者在一行中:

array.partition { |v| v != current_account }.flatten(1)
#=> [1, 2, 4, 5, 6, 7, 8, 3]

# or

array.partition { |v| v != current_account }.inject(:+)
#=> [1, 2, 4, 5, 6, 7, 8, 3]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接