using System.Collections.Generic;
public static void Main()
var list1 = new List<Schema>();
var list2 = new List<Schema>();
var list3 = new List<Schema>();
var list4 = new List<Schema>();
list1.Add(new Schema() { High = 10, Low = 8, OpenValue = 7, Price = 8.5, Time = DateTime.Today.AddDays(-7), Volume = 234234232 });
list2.Add(new Schema() { High = 10, Low = 8, OpenValue = 7, Price = 8.5, Time = DateTime.Today.AddDays(-6), Volume = 234234232 });
list3.Add(new Schema() { High = 10, Low = 8, OpenValue = 7, Price = 8.5, Time = DateTime.Today.AddDays(-7), Volume = 234234232 });
list4.Add(new Schema() { High = 10, Low = 8, OpenValue = 7, Price = 8.5, Time = DateTime.Today.AddDays(-7), Volume = 234234232 });
var list = new List<List<Schema>> { list1, list2, list3, list4 };
var final = list.MatchList();
final.ForEach(d => Console.WriteLine(string.Format("{0}:{1}", final.IndexOf(d), d)));
public int High { get; set; }
public int Low { get; set; }
public int OpenValue { get; set; }
public double Price { get; set; }
public DateTime Time { get; set; }
public int Volume { get; set; }
public override bool Equals(object obj)
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Schema)obj);
protected bool Equals(Schema other)
return High == other.High && Low == other.Low && OpenValue == other.OpenValue && Price.Equals(other.Price) && Time.Equals(other.Time) && Volume == other.Volume;
public override int GetHashCode()
hashCode = (hashCode * 397) ^ Low;
hashCode = (hashCode * 397) ^ OpenValue;
hashCode = (hashCode * 397) ^ Price.GetHashCode();
hashCode = (hashCode * 397) ^ Time.GetHashCode();
hashCode = (hashCode * 397) ^ Volume;
public static class ListExtension
public static List<List<T>> MatchList<T>(this List<List<T>> list) where T : class
var matchedList = new List<Tuple<int, int>>();
for (var i = 0; i < list.Count - 1; i++)
for (var j = i + 1; j < list.Count; j++)
var iElement = list.ElementAt(i);
var jElement = list.ElementAt(j);
if (iElement.Count != jElement.Count) continue;
var flag = !iElement.Where((t, k) => !iElement.ElementAt(k).Equals(jElement.ElementAt(k))).Any();
matchedList.Add(new Tuple<int, int>(i, j));
var item1 = matchedList.Select(d => d.Item1).ToList();
var item2 = matchedList.Select(d => d.Item2).ToList();
var sameGroup = item1.Union(item2);
for (var i = 0; i < list.Count; i++)
if (!sameGroup.Contains(i))