RockyMountainHigh
RockyMountainHigh

Reputation: 3021

Comparing/updating two lists

I have a scenario where we are saving a list of questions and answers for login security. Before saving the answers we are doing a one-way hash for security. Now I have to ad the functionality to accept updates to this list of questions and answers. I will receive a list that contains a list containing the list which contains a questionid and the answer. this new list will be un-hashed and I need to create a final list that contains the unchanged questions and answers as well as the updated ones.

So, I am looking for an elegant way of comparing the two lists and creating a third with the merged results.

Example:

Original list:

  "securityAnswers" : [{
      "question" : 1,
      "answer" : "dfkldlfndajfdkghfkjbgakljdn"
    }, {
      "question" : 2,
      "answerHash" : "ndlknfqeknrkefkndkjsfndskl"
    }, {
      "question" : 5,
      "answerHash" : "ieruieluirhoeiurhoieubn"
    }]

Update list:

  "securityAnswers" : [{
      "question" : 4,
      "answer" : "answer to question 4"
    }, {
      "question" : 2,
      "answerHash" : ""
    }, {
      "question" : 5,
      "answerHash" : "new answer to question 5"
    }]

Merged list:


  "securityAnswers" : [{
      "question" : 4,
      "answer" : "answer to question 4"
    }, {
      "question" : 2,
      "answerHash" : "ndlknfqeknrkefkndkjsfndskl"
    }, {
      "question" : 5,
      "answerHash" : "new answer to question 5"
    }]

The next problem will be hashing the new answers without re-hashing the original. But, I believe I can handle that. I'm just looking for an elegant way to do the merge.

Thanks.

Upvotes: 0

Views: 169

Answers (1)

Tim Schmelter
Tim Schmelter

Reputation: 460038

You can use LINQ. Enumerable.Except returns the set difference. Therefore you need to create a custom IEqualityComparer<Question>:

public class QuestionComparer : IEqualityComparer<Question>
{
    public bool Equals(Question x, Question y)
    {
        return x.Question == y.Question; // assuming that it's a value type like ID (int)
    }

    public int GetHashCode(Question obj)
    {
        return obj.Question.GetHashCode();
    }
}

Now you're ready to use the comparer:

var comparer = new QuestionComparer();
var newQuestions = UpdateList.Except(OriginalList, comparer).ToList();
var both = from o in OriginalList
           join u in UpdateList on o.Question equals u.Question
           select new { o, u };
var updatedQuestions = new List<Question>();
foreach(var x in both)
{
    // modify following accordingly, i take the updated question if the hash contains something, otherwise i use the original question
    if(x.u.AnswerHash != null && x.u.AnswerHash.Length != 0)
        updatedQuestions.Add(x.u);
    else
        updatedQuestions.Add(x.o);
}

Upvotes: 2

Related Questions