Reputation: 119
I have a method that looks like this:
GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
Firstly, the method creates a new List<string>
with all the items from ImportData<string, bool>
that have the value true
and can be found in string[] ItemsToCompare
Secondly, I would like to compare the new List<string>
with the List from AllDrawings<string, List<string>>
. The method is in the end supposed to return a string with the key from AllDrawings<string>, List<String>>
where the two lists match.
I have now spent a lot of hours trying to figure this out myself and also tried every answer I could find to similar questions here on Stackoverflow but with no luck.
Below is the full code for my method. As mentioned above I've tried a lot of different methods to compare the lists but the one following below is the latest try.
public static string GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
{
string FinalDrawing = "";
try
{
List<string> AllCorrect = new List<string>();
foreach (var item in ImportData)
{
if (item.Value == true && ItemsToCompare.Contains(item.Key))
AllCorrect.Add(item.Key);
}
AllCorrect.Sort();
foreach (var DrawItem in AllDrawings)
{
DrawItem.Value.Sort();
var match = AllCorrect.SequenceEqual(DrawItem.Value);
if (match == true)
{
FinalDrawing = DrawItem.Key;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return FinalDrawing;
}
My problem is that the return value from var match = AllCorrect.SequenceEqual(DrawItem.Value);
is false
and therefore the FinalDrawing
is never set.
All answers are very appreciated. Thanks in advance!
Upvotes: 2
Views: 126
Reputation: 335
If the strings really match also for casing your code would be correct. I propose you inspect your string sequences - create an readable string and add appropriate break points. Also try to sort case-insensitive if that is what is missing here
AllCorrect.Sort(StringComparer.InvariantCultureIgnoreCase);
var AllCorrectInfo = string.Join(", ", AllCorrect.ToArray());
foreach (var DrawItem in AllDrawings)
{
DrawItem.Value.Sort();
var DrawItemInfo = string.Join(", ", DrawItem.Value.ToArray());
var match = AllCorrect.SequenceEqual(DrawItem.Value, StringComparer.InvariantCultureIgnoreCase);
if (match == true)
{
FinalDrawing = DrawItem.Key;
}
}
Upvotes: 0
Reputation: 33526
Ok.. I already said that in comments, but just to make sure that you don't get yelled at too much for not-using-linq and such:
your program seems correct up to the point you told us.
Here's a simple test. I provided some stub data that cover all things that you seem to check:
true
things from importedata-> http://rextester.com/HAE73942
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
public class Program
{
// your original function, nothing changed
public static string GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
{
string FinalDrawing = "";
try
{
List<string> AllCorrect = new List<string>();
foreach (var item in ImportData)
{
if (item.Value == true && ItemsToCompare.Contains(item.Key))
AllCorrect.Add(item.Key);
}
AllCorrect.Sort();
foreach (var DrawItem in AllDrawings)
{
DrawItem.Value.Sort();
var match = AllCorrect.SequenceEqual(DrawItem.Value);
if (match == true)
{
FinalDrawing = DrawItem.Key;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return FinalDrawing;
}
public static void Main(string[] args)
{
var allDrawings = new Dictionary<string, List<string>>();
allDrawings.Add("aaa", new List<string>{ "a03", "a01", "a02" }); // originally unsorted
allDrawings.Add("bbb", new List<string>{ "b03", "b01", "b02" }); // originally unsorted
allDrawings.Add("ccc", new List<string>{ "c03", "c01", "c02" }); // originally unsorted
var import = new Dictionary<string, bool>();
import.Add("b01", false); // falsey
import.Add("a05", true); // not in comparison
import.Add("a03", true);
import.Add("c01", false); // falsey
import.Add("a02", true);
import.Add("a04", true); // not in comparison
import.Add("a01", true);
var toCompare = new string[9];
toCompare[0]="a01"; toCompare[1]="a02"; toCompare[2]="a03";
toCompare[3]="b01"; toCompare[4]="b02"; toCompare[5]="b03";
toCompare[6]="c01"; toCompare[7]="c02"; toCompare[8]="c03";
var result = GetDrawing(allDrawings, import, toCompare);
Console.WriteLine("Result: " + result);
}
}
it works fine and prints aaa
as it should.
This means that you had to have overlooked something in the input data. Maybe some strings are uppercase/lowercase? Maybe some strings have whitespaces inside and others not?
Upvotes: 1
Reputation: 13676
This code :
List<string> AllCorrect = new List<string>();
foreach (var item in ImportData)
{
if (item.Value == true && ItemsToCompare.Contains(item.Key))
AllCorrect.Add(item.Key);
}
AllCorrect.Sort();
Can be reduced to :
List<string> AllCorect = ImportData.Where(vp =>
ItemsToCompare.Contains(vp.Key) && vp.Value).Select(vp => vp.Key).OrderBy(vp => vp).ToList();
To solve the second problem you can do :
return AllDrawings.First(l => l.Value.OrderBy(l2 => l2).SequenceEqual(AllCorect)).Key;
P.S.
If First()
always throws an exception then it suggests that problem lays in how this lists are filled with values and this is a different question.
Example :
public static string GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
{
List<string> AllCorect = ImportData.Where(vp =>
ItemsToCompare.Contains(vp.Key) && vp.Value).Select(vp => vp.Key).OrderBy(vp => vp).ToList();
return AllDrawings.First(l => l.Value.OrderBy(l2 => l2).SequenceEqual(AllCorect)).Key;
}
static void Main(string[] args)
{
List<string> list1 = new List<string>() { "one", "two", "three" };
List<string> list2 = new List<string>() { "five", "six", "seven" };
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>()
{
{"first", list1}, {"second", list2}
};
string[] itemsToCompare = { "one", "two", "three" };
var dict2 = new Dictionary<string, bool>()
{
{"one", true},
{"two", true},
{"three", true}
};
var result = GetDrawing(dict, dict2, itemsToCompare);
Console.WriteLine(result);
}
Output : first
Upvotes: 0