Search code examples
c#listerror-handlingsortedlist

How to handle having a duplicate int entered into a 2D SortedList of Int, String


I've no prior experience with SortedLists and have encountered the error "An entry with the same key already exists" due to trying to enter duplicate Ints into the list. This was an oversight on me thinking this wouldn't happen (which was silly).

The list looks like this:

("503", "This is a sentence")
("364", "Oh and another one")
("329", "Yes sentences woo!")
("136", "You gets the point")

The function the error is thrown in is:

    protected void buildSummary()
    {
        scoreCoord2 = -1;
        for (int x1 = 0; x1 < results.Length; x1++)
        {
            SortedList<int, string> paragraphScoreslist = new SortedList<int, string>();
            for (int x2 = 0; x2 < results[x1].Length; x2++)
            {
                scoreCoord2++;
                paragraphScoreslist.Add(intersectionSentenceScores[scoreCoord2], results[x1][x2]);
            }
            var maxValue = paragraphScoreslist.Max(k => k.Key);
            string topSentence = string.Empty;
            if (paragraphScoreslist.TryGetValue(maxValue, out topSentence))
            {
                TextboxSummary.Text += topSentence + "\n";
            }
        }
    }

and the specific line it breaks on is:

    paragraphScoreslist.Add(intersectionSentenceScores[scoreCoord2], results[x1][x2]);

The sorted list contains a sentence of a paragraph and the sentences score which the program calculates. I then need the sentence with the highest score, but don't know to handle this error.

I'm fine with both sentences being "top" and both output somehow, or either one being chosen for top unless there is one already higher.


Solution

  • Instead of using a SortedList, you could create a ScoredSentence class such as

    public class ScoredSentence 
    {
        public string sentence { get; set; }
        public int score { get; set; }
    
        public ScoredSentence(string sentence, int score)
        {
            this.sentence = sentence;
            this.score = score;
        }
    }
    

    And then you can have it all stored in a List, such as

    var s1 = new ScoredSentence("this is a sentence", 2);
    var s2 = new ScoredSentence("hey there buddy", 4);
    var s3 = new ScoredSentence("This is bad", 0);
    var scores = new List<ScoredSentence> {s1,s2,s3};
    

    You can then pull out the max score with

    int max = scores.Max(s => s.score);
    

    Or find a top scored sentence with

    var maxScoredSentence = scores.First(s => s.score == max);
    

    Here's what it might look like in your code

    for (int x1 = 0; x1 < results.Length; x1++)
        {
            List<ScoredSentence> scoreslist = new List<ScoredSentence>();
            for (int x2 = 0; x2 < results[x1].Length; x2++)
            {
                scoreCoord2++;
                scoreslist.Add(new ScoredSentence(results[x1][x2],intersectionSentenceScores[scoreCoord2]));
            }
            var maxValue = scoreslist.Max(s => s.score);
            string topSentence = string.Empty;
    
            TextboxSummary.Text += scoreslist.First(s => s.score == maxValue).sentence + "\n";
    
        }