按表示为字符串的整数排序

时间:2018-07-14 12:21:56

标签: ruby-on-rails arrays ruby sorting

我想通过相关对象的属性值对ActiveRecord对象进行排序。意思是这样的:
物料具有一种具有SKU属性的产品。 SKU主要是存储为字符串的整数,但也可以是字母数字。

sorted = items.sort_by { |item| Integer(item.product.sku) } rescue items

现在,如果发生错误,将返回原始订单的商品。
我想做什么?
扩展Array类以实现类似以下内容:

items.numeric_sort { |item| item.product.sku }

到目前为止我做了什么?
1.构建一个lambda表达式并将其传递

class Array
  def numeric_sort(&lambda)
    if lambda.respond_to? :call
      self.sort_by(&lambda) rescue self
    else
      self.sort_by { |el| Integer(el) } rescue self
    end
  end
end

product_bin = lambda { |task_item| Integer(item.product.bin) }  
items.numeric_sort(&product_bin)

2。从方法链构建lambda表达式

class Object
  def send_chain(keys)
    keys.inject(self, :send)
  end
end

class Array
  def numeric_sort_by(*args)
    (args.length == 1) ? lam = lambda {|el| Integer(el.send(args))} : lam = lambda {|el| Integer(el.send_chain(args))}
    self.sort_by(&lam) rescue self
  end
end

items.numeric_sort_by(:product, :sku)

这一切有意义吗?
如果可以的话,能否请我指出正确的方向来实施我上面提到的语法。
谢谢。

编辑:sku也可以是字母数字。抱歉造成混乱。

2 个答案:

答案 0 :(得分:0)

尝试此解决方案。

没有错误处理。 如果您愿意的话,这只是一个想法。

class Array
  def numeric_sort_by(*args)
    self.sort_by do |element|
      object = element
      args.size.times { |n| object = object.send(args[n]) }
      object.to_f
    end
  end
end

items.numeric_sort_by 'product', 'sku'

答案 1 :(得分:0)

所以简单的实现是:

sorted = items.sort_by { |item| Integer(item.product.sku) } rescue items

所需的是:

items.numeric_sort_by { |item| item.product.sku }

我设法通过在sort_by中产生一个块来实现它:

class Array
  def numeric_sort_by(&block)
    return to_enum :numeric_sort_by unless block_given?
    self.sort_by { |element| Integer(yield(element)) } rescue self
  end
end