I have a set of object, each time I will get two objects in the set and do something according to the combination of two object.
the sample will like:
List list = ["A", "B"]
if(list.contains("A") && list.contains("B")){
decision1()
}
else if(list.contains("A") && list.contains("C")){
decision2()
}
else if(list.contains("A") && list.contains("D")){
decision2()
}
else if(list.contains("B") && list.contains("C")){
decision3()
}
else if(list.contains("B") && list.contains("D")){
decision1()
}
else if(list.contains("C") && list.contains("D")){
decision3()
}
I used if-else to consider all combination case but now I have 7 types in the set that says I need to write 21 if-else condition to include all possible combination. since there only have 4 decisions.
Is there any better design to refactor?
CodePudding user response:
I don't know C#, but maybe this python code can give you a little inspiration
from itertools import combinations
a = [i for i in "ABC"]
b = {1: [('A', 'B'), ('B', 'C')], 2: [('A', 'C')]}
for e in combinations(a, 2):
if e in b[1]:
print(e, "decision1")
elif e in b[2]:
print(e, "decision2")
CodePudding user response:
Why don't we extract these rules into a collection? In case of c# it can be a List<T>
:
// readonly IReadOnlyList<...> to prevent from unwanted (occasional) changing
private static readonly IReadOnlyList<(string[] contains, Action action)> rules =
new List<(string[] contains, Action action)>() {
(new string[] { "A", "B" }, () => decision1()),
(new string[] { "A", "C" }, () => decision2()),
(new string[] { "A", "D" }, () => decision2()),
(new string[] { "B", "C" }, () => decision3()),
(new string[] { "B", "D" }, () => decision1()),
(new string[] { "C", "D" }, () => decision3()),
// Add more rules here
};
and then we can easily test these rules with a help of Linq:
using System.Linq;
...
rules
.FirstOrDefault(rule => rule.contains.All(item => list.Contains(item)),
(null, () => {}))
.action();
CodePudding user response:
Guessing you want to check always in combination for your first and second list. Therefore I am naming them list1 and list2. Probably there is a way to work also with switches but my recommendation would be to group them in a nested way.
List list1 = ["A", "B", "C", "D"]
List list2 = ["A", "B"]
if (list1.contains("A")) {
if(list2.contains("B")) {decision1()}
else if (list2.contains("C") || list2.contains("D")) {decision2()}
else { /* do nothing */}
}
else if (list1.contains("B")) {
if(list2.contains("C")) {decision3()}
else if (list2.contains("D")) {decision1()}
else { /* do nothing */}
}
else if (list1.contains("C")) {
if(list2.contains("D")) {decision3()}
else { /* do nothing */}
}