Ruby on rails 更正我的代码:按2个属性对u进行排序,如果第一个属性为',则第一个属性服从第二个属性;这是两个值中的一个
鉴于: 我想根据两条规则进行排序:Ruby on rails 更正我的代码:按2个属性对u进行排序,如果第一个属性为',则第一个属性服从第二个属性;这是两个值中的一个,ruby-on-rails,ruby,sorting,Ruby On Rails,Ruby,Sorting,鉴于: 我想根据两条规则进行排序: 卡或条带支付方式应首先显示,然后按金额从低到高排序 任何其他付款方式都应该显示在最后,然后按金额从低到高排序 我当前的代码是将卡片或条纹移动到前面,但不按金额排序: charges = [ {payment_method:"card",amount:1000}, {payment_method:"stripe",amount:500}, {payment_method:"stripe",amount:1500}, {payment_method
charges = [
{payment_method:"card",amount:1000},
{payment_method:"stripe",amount:500},
{payment_method:"stripe",amount:1500},
{payment_method:"card",amount:2000},
{payment_method:"cash",amount:200},
{payment_method:"cash",amount:4000},
]
您的代码的问题(除了缺少
end
语句,我希望它在剪切粘贴后无法保存)是哈希没有键“payment\u method”
和“amount”
(charges.first.keys#=>[:payment\u method,:amount]
):-)
通过更正,您的代码可以正常工作:
charges.sort_by do |obj|
[
(["card","stripe"].include? obj["payment_method"]) ? 0 : 1 ,
obj["amount"]
]
# result of MY sort:
charges = [
{:payment_method=>"card", :amount=>1000},
{:payment_method=>"stripe", :amount=>500},
{:payment_method=>"stripe", :amount=>1500},
{:payment_method=>"card", :amount=>2000},
{:payment_method=>"cash", :amount=>200},
{:payment_method=>"cash", :amount=>4000},
]
# result of DESIRED sort:
charges = [
{:payment_method=>"stripe", :amount=>500},
{:payment_method=>"card", :amount=>1000},
{:payment_method=>"stripe", :amount=>1500},
{:payment_method=>"card", :amount=>2000},
{:payment_method=>"cash", :amount=>200},
{:payment_method=>"cash", :amount=>4000},
]
让我们更仔细地看看您的代码在做什么
因为散列没有键“payment_method”
和“amount”
,obj[“payment_method”]#=>nil
和obj[“amount”]#=>nil
表示所有obj
。所以,
charges.sort_by {|h| [["card", "stripe"].include?(h[:payment_method]) ? 0 : 1, h[:amount]]}
# [{:payment_method=>"stripe", :amount=> 500},
# {:payment_method=>"card", :amount=>1000},
# {:payment_method=>"stripe", :amount=>1500},
# {:payment_method=>"card", :amount=>2000},
# {:payment_method=>"cash", :amount=> 200},
# {:payment_method=>"cash", :amount=>4000}]
变成
["card","stripe"].include? obj["payment_method"]
对于所有obj
,这是false
。因此,所使用的排序数组的第一个元素始终是1
sort\u by
用于排序数组。1在比较obj1[“amount”]
和obj2[“amount”]
时,使用在obj1
和obj2
类上定义的实例方法
。在这种情况下
["card","stripe"].include? nil
obj1[“金额”]obj2[“金额”]#=>nil nil
我们从
obj1["amount"] <=> obj2["amount"] #=> nil <=> nil
nil.method(:).owner#=>内核
Array.祖先#=>[数组,可枚举,对象,内核,基本对象]
NilClass
有一个实例方法
,它从Kernel
(2)获取,每当被比较的对象相等时,该实例方法返回零(这里nil nil#=>0
)。因此,排序比较总是[1,nil][1,nil]
,这意味着排序实际上是随机的
1参见后一份文件——具体来说,第三段——以了解如何做到这一点
2要理解为什么
Kernel 35;
被记录在中,请参见链接的第三段。ok,那么您所做的就是移动括号。。。但是就像。。。为什么会这样???为什么我的答案没有呢?詹姆斯,当我发布我的答案时我很匆忙,所以没有仔细看你的答案。我只是做了一个编辑来解释为什么你的代码不起作用。哦。。。字符串vs符号也是一些代码被复制/粘贴的症状,一些代码只是匆匆写在这里。。。
nil.method(:<=>).owner #=> Kernel
Array.ancestors #=> [Array, Enumerable, Object, Kernel, BasicObject]