0

I have some JSON similar to this coming over from a call to GoToWebinar's API:

[
   {
      "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?"
   }
]

It will be serialized using JSON.Net to populate these classes:

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

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

I'd like the WebinarQuestions.questions to be in order. Is there a way to do this without iterating over the JSON?

I don't know why they come over in that order and don't really have any control over them.

5
  • 3
    What are the performance implications of just sorting them in memory after you've deserialized the JSON? Commented Dec 11, 2015 at 21:43
  • 2
    what order do they currently come over in for all we know they are coming over in the correct order.. also since it's a List<T> can you not order the list..? Commented Dec 11, 2015 at 21:44
  • reorder it after you have your objects. You don't want to parse the JSON to chaange the ordering. I'm not even sure you can guarantee ordering when deserializing. Commented Dec 11, 2015 at 21:45
  • I understand the order in the JSON is wrong and he has no control over it, he wants the question to be ordered by number. I would assume a basic sort call using the question value for ordering. Commented Dec 11, 2015 at 21:46
  • Deserialize first and then sort it. Of course, you are going to have to parse the question field to figure out what order they should be in, which is pretty ugly. Actually, on second thoughts, because they start with the number, so long as there are less than 9 you could just sort the strings, but that's pretty hacky. Commented Dec 11, 2015 at 21:46

4 Answers 4

2

As long as the questions all follow a pattern of number. question then the following will sort them after deserialization:

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

It's hacky but it handles question numbers greater than 9.

Sign up to request clarification or add additional context in comments.

Comments

1

Do this:

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();

questions are now in order.

Cheers

EDIT: As pointed out, my original answer would not have worked for more than 9 questions. Now, as others have done and using Split, of course we must do some form of error checking in case the format is wrong.

I have decided to leave this out for brevity.

3 Comments

@Shevek true. Let me fix it.
What if there is a period in the question?
Like I said, there needs to be some validation on the input format, and I think the original question was more about the concept around ordering the data, not how to fool proof it at 100%. If you have a separate concern, then I think it might add more value to the Q&A format of this site if you created a separate question.
1

Any reason you couldn't use Enumerable.OrderBy?

First deserialize the JSON into List<WebinarQuestion> Enumberable object then sort it using OrderBy

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

4 Comments

Would that "rewrite" the object in the correct order?
I'm not sure what you mean by rewrite. It would reorder the items in the list. My answer assumes you've already deserialized the json into an Enumerable object. Editing the answer to make this more clear...
this won't handle more than 9 questions
The data format doesn't allow for handling ordering of 9 questions without more logic regardless of how you sort it. The question wasn't asking how to solve that problem, it was asking how to sort a json list before deserialization. The answer is don't.
1

Make your WebinarQuestion class implement IComparable, this will handle multi digit question numbers:

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]); 
        }
    }
}

Then deserialize to list:

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

Edit: if you want to keep your WebinarQuestions class:

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);
   }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.