【问题标题】:Move x element to the end of an array将 x 元素移动到数组的末尾
【发布时间】:2017-09-03 18:13:19
【问题描述】:

我正在尝试找到一种方法来获取特定关系并将其移动到数组的末尾。基本上,我有一个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 %>

此当前返回按 created_at 帐户排序的列表。我不希望它按创建时间排序,但 current_account 位于底部,所以我创建了一个名为 current_sort 的范围,但我不确定在这里做什么。

CURRENT_SORT SCOPE ON ACCOUNT

 scope :current_sort, lambda { |account|

 }

我希望这个范围在关联数组中最后返回传入的帐户。如何使用 SQL 或 Ruby 做到这一点?

【问题讨论】:

  • 为什么不只是sort_by { |v| v == current_account ? 1 : 0 }
  • @tadman 效果很好!没有理由不这样做。
  • 你也可以使用list - [ current_account ] + [ current_account ],但这看起来更麻烦。
  • 是的,不过这很有趣。

标签: arrays ruby arel


【解决方案1】:

将特定元素排序到数组末尾的快速技巧是:

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 在回答中使用的方法的一种变体。

【讨论】:

  • 太好了。请注意,array - to_end + to_end 只能以类似的方式工作。 [1,1,1,1,1,2]-[1]==[2]
  • Ruby 的 sort / sort_by 不稳定。您的解决方案将current_account 放在最后,但它可能会无意中重新排序剩余的项目。这可以通过考虑每个项目的索引来解决,即:array.sort_by.with_index { |v, i | [v == current_account ? 1 : 0, i] }
  • @Stefan 说得好。我已经添加了另外两种方法来解决这个问题,其中一种显然你已经提到过,我已经检查过了。
  • 为什么你有(array.length + i) : i 而不仅仅是1 : 0?考虑到以下, i,这似乎是多余的,但也许我遗漏了一些东西。
  • @Stefan 啊,我明白你在该数组中使用辅助排序因子的意思了。
【解决方案2】:

您可以使用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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多