【问题标题】:JSON.Net - Reordering JSON when serializingJSON.Net - 序列化时重新排序 JSON
【发布时间】:2015-12-11 21:41:41
【问题描述】:

我通过调用 GoToWebinar 的 API 获得了一些类似于此的 JSON:

[
   {
      "answer":"The Answer for Question 1",
      "question":"1. This is the Question?"
   },
   {
      "answer":"The Answer for Question 2",
      "question":"2. This is the Question?"
   },
   {
      "answer":"The Answer for Question 7",
      "question":"7. This is the Question?"
   },
   {
      "answer":"The Answer for Question 5",
      "question":"5. This is the Question?"
   },
   {
      "answer":"The Answer for Question 3",
      "question":"3. This is the Question?"
   },
   {
      "answer":"The Answer for Question 8",
      "question":"8. This is the Question?"
   },
   {
      "answer":"The Answer for Question 4",
      "question":"4. This is the Question?"
   },
   {
      "answer":"The Answer for Question 6",
      "question":"6. This is the Question?"
   }
]

它将使用 JSON.Net 序列化以填充这些类:

public class WebinarQuestions {
    public List<WebinarQuestion> questions { get; set; }
}

public class WebinarQuestion {
    public string answer { get; set; }
    public string question { get; set; }
}

我希望 WebinarQuestions.questions 井井有条。有没有办法在不遍历 JSON 的情况下做到这一点?

我不知道他们为什么按这个顺序过来,并且对他们没有任何控制权。

【问题讨论】:

  • 在反序列化 JSON 后仅在内存中对它们进行排序对性能有何影响?
  • 他们目前的顺序是什么,因为我们知道他们的顺序是正确的。而且因为它是一个列表,你可以不排序列表吗?
  • 在您拥有对象后重新排序。您不想解析 JSON 来更改排序。我什至不确定反序列化时是否可以保证订购。
  • 我知道 JSON 中的顺序是错误的,他无法控制它,他希望问题按数字排序。我会假设一个基本的排序调用使用问题值进行排序。
  • 先反序列化再排序。当然,您将不得不解析question 字段来确定它们应该是什么顺序,这非常难看。实际上,再想一想,因为它们以数字开头,只要少于9,您就可以对字符串进行排序,但这很hacky。

标签: c# json json.net


【解决方案1】:

只要问题都遵循number. question的模式,那么反序列化后以下将对其进行排序:

webinarQuestions.questions = webinarQuestions.questions
    .OrderBy(q => int.Parse(q.question.Split('.')[0])).ToList();

它很 hacky,但它可以处理大于 9 的问题。

【讨论】:

    【解决方案2】:

    这样做:

    string jsonQuestions = @"[
    {
      ""answer"":""The Answer for Question 1"",
      ""question"":""1. This is the Question?""
    },
    {
      ""answer"":""The Answer for Question 2"",
      ""question"":""2. This is the Question?""
    },
    {
      ""answer"":""The Answer for Question 7"",
      ""question"":""7. This is the Question?""
    },
    {
      ""answer"":""The Answer for Question 5"",
      ""question"":""5. This is the Question?""
    },
    {
      ""answer"":""The Answer for Question 3"",
      ""question"":""3. This is the Question?""
    },
    {
      ""answer"":""The Answer for Question 8"",
      ""question"":""8. This is the Question?""
    },
    {
      ""answer"":""The Answer for Question 4"",
      ""question"":""4. This is the Question?""
    },
    {
      ""answer"":""The Answer for Question 6"",
      ""question"":""6. This is the Question?""
    }
    ]";
    
    WebinarQuestions wq = new WebinarQuestions();
    wq.questions = JsonConvert.DeserializeObject<List<WebinarQuestion>>(jsonQuestions).OrderBy(x => x.question.Split('.')[0]).ToList();
    

    现在有问题了。

    干杯

    编辑:正如所指出的,我最初的答案不会超过 9 个问题。现在,正如其他人使用Split 所做的那样,当然我们必须进行某种形式的错误检查,以防格式错误。

    为了简洁起见,我决定将其省略。

    【讨论】:

    • @Shevek 是的。让我解决它。
    • 问题中有句号怎么办?
    • 就像我说的,需要对输入格式进行一些验证,我认为最初的问题更多是关于排序数据的概念,而不是如何以 100% 的方式进行傻瓜证明。如果您有一个单独的问题,那么我认为如果您创建一个单独的问题,它可能会为本网站的问答格式增加更多价值。
    【解决方案3】:

    您不能使用 Enumerable.OrderBy 的任何原因?

    首先将 JSON 反序列化为 List&lt;WebinarQuestion&gt; Enumberable 对象,然后使用 OrderBy 对其进行排序

    questions = questions.OrderBy(x => x.question);
    

    【讨论】:

    • 会以正确的顺序“重写”对象吗?
    • 我不确定你所说的重写是什么意思。它将重新排序列表中的项目。我的回答假设您已经将 json 反序列化为 Enumerable 对象。编辑答案以使这一点更清楚......
    • 这不会处理超过 9 个问题
    • 无论您如何排序,数据格式都不允许在没有更多逻辑的情况下处理 9 个问题的排序。问题不是问如何解决这个问题,而是问如何在反序列化之前对 json 列表进行排序。答案是不要。
    【解决方案4】:

    让您的 WebinarQuestion 类实现 IComparable,这将处理多位问题编号:

    public class WebinarQuestion : IComparable<WebinarQuestion> {
        public string answer { get; set; }
        public string question { get; set; }
    
        public int CompareTo(WebinarQuestion other)
        { 
            return QuestionNumber.CompareTo(other.QuestionNumber);
        }
    
        private int QuestionNumber 
        { 
            get 
            { 
                // Or write more robust parsing if format differs
                return Int32.Parse(question.Split('.')[0]); 
            }
        }
    }
    

    然后反序列化到列表:

    var questions = JsonConvert.DeserializeObject<List<WebinarQuestion>>(json).OrderBy(x => x).ToList();
    

    编辑:如果你想保留你的 WebinarQuestions 类:

    public class WebinarQuestions 
    {
       public WebinarQuestions(IEnumerable<WebinarQuestion> questions)
       {
           Questions = questions.OrderBy(x => x).ToList();
       }
    
       public IReadOnlyList<WebinarQuestion> Questions { get; private set; }
    
       public static WebinarQuestions FromJson(string json)
       {
           var questions = JsonConvert.DeserializeObject<List<WebinarQuestion>>(json);
           return new WebinarQuestions(questions);
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-27
      • 2016-08-20
      相关资源
      最近更新 更多