Having a list of structs OR maybe an array List each with 3 elements, like
12 8 7
5 1 0
7 3 2
10 6 5
6 2 1
8 4 3
6 1 5
7 2 6
8 3 7
9 4 8
11 7 6
13 9 8
11 6 10
12 7 11
13 8 12
14 9 13
I want to get rid of items that have 2 common subitems in list, in the example I would like to remove
5 1 0
6 2 1
6 1 5
7 3 2
7 2 6
8 4 3
8 3 7 has 2 same items as row 7,3,2
9 4 8 has 2 same items as row 8,4,3
10 6 5
11 7 6
11 6 10 has 2 same items as row 11,7,6
12 7 11 has 2 same items as row 11,7,10
12 8 7
13 8 12
13 9 8
14 9 13 has 2 same items as row 13,9,8
So using structs approach I am thinking in sorting the list by element A, then looping and comparing elements, in a way that If current element has 2 values equal to other element in list I do not add it to a result List, however I got stuck and do not know if there is a better approach
struct S
{
public int A;
public int B;
public int C;
}
public void test()
{
List<S> DataItems = new List<S>();
DataItems.Add(new S { A = 1, B = 2, C=3} );
DataItems.Add(new S { A = 12, B = 8, C = 7 });
DataItems.Add(new S { A = 5, B = 1, C = 0 });
DataItems.Add(new S { A = 7, B = 3, C = 2 });
DataItems.Add(new S { A = 10, B = 6, C = 5 });
DataItems.Add(new S { A = 6, B = 2, C = 1 });
DataItems.Add(new S { A = 8, B = 4, C = 3 });
DataItems.Add(new S { A = 6, B = 1, C = 5 });
DataItems.Add(new S { A = 7, B = 2, C = 6 });
DataItems.Add(new S { A = 8, B = 3, C = 7 });
DataItems.Add(new S { A = 9, B = 4, C = 8 });
DataItems.Add(new S { A = 11, B = 7, C = 6 });
DataItems.Add(new S { A = 13, B = 9, C = 8 });
DataItems.Add(new S { A = 11, B = 6, C = 10 });
DataItems.Add(new S { A = 12, B = 7, C = 11 });
DataItems.Add(new S { A = 13, B = 8, C = 12 });
DataItems.Add(new S { A = 14, B = 9, C = 13 });
var sortedList = DataItems.OrderBy(x => x.A);
List<S> resultList = new List<S>();
for (int i = 0; i < sortedList.Count (); i++)
{
for (int j = i+1; j < sortedList.Count(); j++)
{
if (sortedList.ElementAt(i).A == sortedList.ElementAt(j).A || sortedList.ElementAt(i).A == sortedList.ElementAt(j).B || sortedList.ElementAt(i).A == sortedList.ElementAt(j).C)
{
//ONE HIT, WAIT OTHER
}
}
}
}
Is there a more efficient way to get the list without having item with 2 same items so I would get, instead of hardcoding the solution?
5 1 0
6 2 1
6 1 5
7 3 2
7 2 6
8 4 3
10 6 5
11 7 6
12 8 7
13 8 12
13 9 8
Given an item...
{ A = 1, B = 2, C = 3 }
You have 3 possible combinations that could be repeated in another item, e.g.
AB, AC & BC which is {1, 2}, {1, 3} & {2, 3}
So what I would do is iterate through your list, add those combinations to a dictionary with a separator char (lowest number first so if B < A then add BA rather than AB). So you dictionary keys might be...
"1-2", "1-3", "2-3"
Now as you add each item, check if the key already exists, if it does then you can ignore that item (don't add it to the results list).
Performance-wise this would be once through the whole list and using the dictionary to check for items with 2 common numbers.
One way to solve it is by introducing intermediate methods in the struct S
:
public struct S {
public int A;
public int B;
public int C;
public bool IsSimilarTo(S s) {
int similarity = HasElement(A, s) ? 1 : 0;
similarity += HasElement(B, s) ? 1 : 0;
return similarity >= 2 ? true : HasElement(C, s);
}
public bool HasElement(int val, S s) {
return val == s.A || val == s.B || val == s.C;
}
public int HasSimilarInList(List<S> list, int index) {
if (index == 0)
return -1;
for (int i = 0; i < index; ++i)//compare with the previous items
if (IsSimilarTo(list[i]))
return i;
return -1;
}
}
Then you can solve it like this without ordering:
public void test() {
List<S> DataItems = new List<S>();
DataItems.Add(new S { A = 1, B = 2, C = 3 });
DataItems.Add(new S { A = 12, B = 8, C = 7 });
DataItems.Add(new S { A = 5, B = 1, C = 0 });
DataItems.Add(new S { A = 7, B = 3, C = 2 });
DataItems.Add(new S { A = 10, B = 6, C = 5 });
DataItems.Add(new S { A = 6, B = 2, C = 1 });
DataItems.Add(new S { A = 8, B = 4, C = 3 });
DataItems.Add(new S { A = 6, B = 1, C = 5 });
DataItems.Add(new S { A = 7, B = 2, C = 6 });
DataItems.Add(new S { A = 8, B = 3, C = 7 });
DataItems.Add(new S { A = 9, B = 4, C = 8 });
DataItems.Add(new S { A = 11, B = 7, C = 6 });
DataItems.Add(new S { A = 13, B = 9, C = 8 });
DataItems.Add(new S { A = 11, B = 6, C = 10 });
DataItems.Add(new S { A = 12, B = 7, C = 11 });
DataItems.Add(new S { A = 13, B = 8, C = 12 });
DataItems.Add(new S { A = 14, B = 9, C = 13 });
int index = 1; //0-th element does not need to be checked
while (index < DataItems.Count) {
int isSimilarTo = DataItems[index].HasSimilarInList(DataItems, index);
if (isSimilarTo == -1) {
++index;
continue;
}
DataItems.RemoveAt(index);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With