What I need to know:
I only require a true or false answer: Compare each of the Legs by their locations and return true if they are.
What I don't need to know:
Order of locations is irrelevant and duplication is irrelevant.
Data Structure:
CoachDriverItenaryModel (1-*) Leg
Leg (1-*) Exhibitions
(each exhibition has the Location field)
e.g. (simplified in pseudo code... note x,y,z represent locations)
Example 1: The answer should be true...(order is irrelevant)
ListOfLegs.Add(leg1: x,y,z)
ListOfLegs.Add(leg2: z,x,y)
ListOfLegs.Add(leg3: y,z,x)
var answer = ListOfLegs(AreAllLocationsSameOnAllLegs);
Example 2: The answer should be true...(duplication is irrelevant)
ListOfLegs.Add(leg1: x,y,z,y,y,y,y,y)
ListOfLegs.Add(leg2: z,x,y)
var answer = ListOfLegs(AreAllLocationsSameOnAllLegs);
Example 3: The answer should be false...(because no 'z' on leg1)
ListOfLegs.Add(leg1: x,y)
ListOfLegs.Add(leg2: z,x,y)
var answer = ListOfLegs(AreAllLocationsSameOnAllLegs);
Example 4: The answer should be false...(because no 'z' on leg 4)
ListOfLegs.Add(leg1: x,y,z)
ListOfLegs.Add(leg2: z,x,y)
ListOfLegs.Add(leg3: z,x,y,y,y,y)
ListOfLegs.Add(leg4: x,x,y,x,x)
var answer = ListOfLegs(AreAllLocationsSameOnAllLegs);
I'm looking for a nice Linq statement or something that doesn't require a lengthy algorithm?
below is a project that can be pasted straight in to .Net Fiddle (remember to set the compiler option to Rosyln) and the method to replace is below (it works but is there a better way?)...
public bool CompareAllLegLocations(){}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var bradford = new Exhibition() { Location = "Bradford", Type = "Eygptian", Price = "£2.00" };
var leeds = new Exhibition() { Location = "Leeds", Type = "Dinosaurs", Price = "£2.00" };
var batley = new Exhibition() { Location = "Batley", Type = "Samurai", Price = "£2.00" };
var york = new Exhibition() { Location = "York", Type = "Vikings", Price = "£2.00" };
var mondaysItenary = new CoachDriverItenaryModel("Monday");
mondaysItenary.AddLeg(new Leg { LegNumber = 1, Exhibitions = new List<Exhibition>() { york, leeds, bradford, leeds, york } });
mondaysItenary.AddLeg(new Leg { LegNumber = 2, Exhibitions = new List<Exhibition>() { batley, leeds, bradford } });
var tuesdaysItenary = new CoachDriverItenaryModel("Tuesday");
tuesdaysItenary.AddLeg(new Leg { LegNumber = 1, Exhibitions = new List<Exhibition>() { leeds, batley, leeds } });
tuesdaysItenary.AddLeg(new Leg { LegNumber = 2, Exhibitions = new List<Exhibition>() { batley, leeds, batley} });
var wednesdaysItenary = new CoachDriverItenaryModel("Wednesday");
wednesdaysItenary.AddLeg(new Leg { LegNumber = 1, Exhibitions = new List<Exhibition>() { leeds, bradford, batley } });
wednesdaysItenary.AddLeg(new Leg { LegNumber = 2, Exhibitions = new List<Exhibition>() { bradford, batley, bradford } });
wednesdaysItenary.AddLeg(new Leg { LegNumber = 3, Exhibitions = new List<Exhibition>() { bradford, batley, leeds } });
var thursdaysItenary = new CoachDriverItenaryModel("Thursday");
thursdaysItenary.AddLeg(new Leg { LegNumber = 1, Exhibitions = new List<Exhibition>() { leeds, bradford, batley, york, leeds } });
thursdaysItenary.AddLeg(new Leg { LegNumber = 2, Exhibitions = new List<Exhibition>() { batley, bradford, leeds, york } });
//mondaysItenary.DumpToConsole();
mondaysItenary.CheckHasSameLocations(); //true: because same locations on all legs (regardless of order)
Console.WriteLine("-------------------------------");
//tuesdaysItenary.DumpToConsole();
tuesdaysItenary.CheckHasSameLocations(); //false: because "york" is not on both legs
Console.WriteLine("-------------------------------");
//wednesdaysItenary.DumpToConsole();
wednesdaysItenary.CheckHasSameLocations(); //false: because first leg has "batley" on it and the other leg doesn't
Console.WriteLine("-------------------------------");
//thursdaysItenary.DumpToConsole();
thursdaysItenary.CheckHasSameLocations(); //true: because duplication is allowed so it's okay to go to leeds twice
Console.WriteLine("Finished");
}
}
public class CoachDriverItenaryModel
{
private Dictionary<int, Leg> LegNumberToLegIndex { get; set; }
public IEnumerable<Leg> Legs => LegNumberToLegIndex?.Values; //null propagation operator (c# 6+) use Rosyln 1.0.0 compiler
public string Day { get; set; }
public CoachDriverItenaryModel(string day) //constructor
{
LegNumberToLegIndex = new Dictionary<int, Leg>();
Day = day;
}
public void AddLeg(Leg leg)
{
if (LegNumberToLegIndex == null)
{
LegNumberToLegIndex = new Dictionary<int, Leg>();
}
if (!LegNumberToLegIndex.ContainsKey(leg.LegNumber))
{
LegNumberToLegIndex.Add(leg.LegNumber, leg);
}
}
public void DumpToConsole()
{
Console.WriteLine($"Day: {this.Day}");
foreach (var displayLeg in this.Legs)
{
Console.WriteLine($"leg: {displayLeg.LegNumber}");
foreach (var exhibition in displayLeg.Exhibitions)
{
Console.WriteLine($"Exhibition: {exhibition.Location}, Type: {exhibition.Type}, Price:{exhibition.Price}");
}
}
}
public bool CheckHasSameLocations()
{
if (LegNumberToLegIndex.Count <= 1) return true;
for (var i=0; i < LegNumberToLegIndex.Count()-1; i++)
{
Leg leg = LegNumberToLegIndex[LegNumberToLegIndex.ElementAt(i).Key];
Leg nextLeg = LegNumberToLegIndex[LegNumberToLegIndex.ElementAt(i + 1).Key];
var legUnqOrd = from l in leg.Exhibitions.Distinct()
orderby l.Location
select new { l.Location };
var nextLegUnqOrd = from l in nextLeg.Exhibitions.Distinct()
orderby l.Location
select new { l.Location };
if (!legUnqOrd.SequenceEqual(nextLegUnqOrd))
{
Console.WriteLine("!Locations are different!");
return false;
}
}
Console.WriteLine("Locations Match");
return true;
}
}
public class Leg
{
public int LegNumber { get; set; }
public List<Exhibition> Exhibitions { get; set; }
}
public class Exhibition
{
public string Location { get; set; }
public string Type { get; set; }
public string Price { get; set; }
}