【问题标题】:How to sort a nested array of JSON objects in Ruby?如何在 Ruby 中对 JSON 对象的嵌套数组进行排序?
【发布时间】:2018-09-10 09:47:31
【问题描述】:

早上好!我有一个棘手的数据集可以在 Rails 中使用。它是一组 JSON 对象的数组,每个对象有 4 个属性。示例如下:

[
    [
        {
            "column_name": "ID",
            "column_id": "item_attributes#id",
            "column_value": "25295119-7113-42fe-90d5-394c7a841b31",
            "column_type": "string"
        },
        {
            "column_name": "Name",
            "column_id": "item_attributes#name",
            "column_value": "Webform submission",
            "column_type": "string"
        },
        {
            "column_name": "Current owner",
            "column_id": "item_attributes#current_owner",
            "column_value": "Joe Bloggs",
            "column_type": "string"
        },
        {
            "column_name": "State",
            "column_id": "item_attributes#state",
            "column_value": "New Task",
            "column_type": "string"
        },
        {
            "column_name": "Status",
            "column_id": "item_attributes#status",
            "column_value": "In progress",
            "column_type": "string"
        },
        {
            "column_name": "Created at",
            "column_id": "item_attributes#created_at",
            "column_value": "07/09/2018, 10:47 am",
            "column_type": "datetime"
        },
        {
            "column_name": "Updated at",
            "column_id": "item_attributes#updated_at",
            "column_value": "07/09/2018, 10:47 am",
            "column_type": "datetime"
        },
        {
            "column_name": "Task reviewer",
            "column_id": "item_participant_attributes#90a76abe-028f-45bc-8390-433bc39ba02e",
            "column_value": "Jane Bloggs",
            "column_type": "string"
        },
        {
            "column_name": "Task owner",
            "column_id": "item_participant_attributes#5bce3a02-07bf-4353-9f3d-2cc60f787584",
            "column_value": "Jack blogs",
            "column_type": "string"
        },
        {
            "column_name": "Make a list of your weekly tasks. Update status of this object to complete when it's complete.",
            "column_id": "element_attributes#533e26d8-c313-4d94-ab99-37263b0aa4ee",
            "column_value": null,
            "column_type": "string"
        },
        {
            "column_name": "Set target end date (choose Friday for end of this week)",
            "column_id": "element_attributes#6eeddd67-e1de-40c3-b220-197ddf554241",
            "column_value": null,
            "column_type": "datetime"
        },
        {
            "column_name": "Reviewer comments (optional)",
            "column_id": "element_attributes#3923358c-85f0-444b-9287-4738d9148eb9",
            "column_value": null,
            "column_type": "string"
        }
    ], 
    [...]
]

我有一个名为 ReportTemplateColumn 的模型,它定义了每个项目所需的 sort_prioritysort_direction,以及相关的 column_id

我需要遍历ReportTemplateColumns 并将其排序方向按优先级顺序应用于上述数据集。

例如,我知道我需要按column_id = item_attributes#name 对数据集重新排序,以便按desc 排序。数组数组需要根据column_value值改变顺序。

我的尝试

  def set_sorted_data(data)
    @new_data = data
    self.report_template.report_template_columns.where('sort_priority != ?', 1000).order(:sort_priority).each do |report_template_column|
      @new_data = @new_data.sort_by { |x| x[0]["column_value"] }
    end
    return @new_data
  end

【问题讨论】:

    标签: ruby-on-rails json ruby


    【解决方案1】:

    我相信.sort_by { |x| x[0]["column_value"] } 是主要问题,例如,如果您遇到这样的问题。

    f = [[{'a' => 4}, {'a' => 2}]]
    # => [[{"a"=>4}, {"a"=>2}]]
    f.sort_by{|d| d[0]['a']}
    # => [[{"a"=>4}, {"a"=>2}]], won't change anything
    f.first.sort_by{|d| d['a'] } # first represent the [0] here
    # => [{"a"=>2}, {"a"=>4}], This gonna work
    

    使用你的方法有问题,你正在对外部数组进行排序,当它像这样 { |x| x[0]["column_value"] } 987654326@,但是指定你在内部数组上的工作会影响内部数组,就像上面的例子一样,希望它对你有用。

    您可以使用sort_by! 对其进行就地排序。

    【讨论】:

    • 谢谢你,它为我指明了正确的方向。我的实现现在也作为答案发布。
    【解决方案2】:

    下面是一个有效的实现,可能这不是最佳的,但它有效:

      def set_sorted_data(data)
        @new_data = data
        self.report_template.report_template_columns.where('sort_priority != ?', 1000).order(:sort_priority).reverse.each_with_index do |report_template_column|
          @new_data[0].each_with_index do |item_row_datum, index|
            if item_row_datum[:column_id] == report_template_column.column_id
              @index = index
            end
          end
          if report_template_column.column_type == 'number'
            @new_data.sort_by! { |item_row_datum| item_row_datum[@index][:column_value].to_i }
          elsif report_template_column.column_type == 'datetime'
            @new_data.sort_by! { |item_row_datum| item_row_datum[@index][:column_value].to_date }
          else
            @new_data.sort_by! { |item_row_datum| item_row_datum[@index][:column_value].to_s }
          end
          if report_template_column.sort_direction == 'desc'
            @new_data = @new_data.reverse
          end
        end
        return @new_data
      end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-22
      • 1970-01-01
      • 2019-09-30
      • 2012-11-25
      • 2016-07-01
      • 1970-01-01
      相关资源
      最近更新 更多