Reputation: 3021
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
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