C
C#4mo ago
Sygmond

How to implement alternative items. A is alt. to B and C => B alt. to A and C, etc.

How is this usually designed? An item with alternative items. For example B is alternative to A. That means A is alternative to B too. If I create C alternative to A, A and B become alternatives to C. Each one is an alternative to each other. Now imagine you have a tab for each (A, B, C) where you have the rows of alternatives. A Sync service has to update each tab when an alternative is added anywhere in the tabs. How would you implement this at the db or object level?
18 Replies
Joschi
Joschi4mo ago
I'm not entirely sure what you mean by "Alternative Item". But it sounds a bit like you need an abstract base class and then handle each inheriting type individually on the UI level. In the database you can just use a "table per hierarchy mapping". If you use EFCore it can handle that for you and there is a lot of documentation out there on how to do that.
Sygmond
Sygmond4mo ago
currently is implemented like this
using System;
using System.Collections.Generic;

public class Program
{
public static void Main()
{
// we have 3 items: A, B and C
var a = new Item {Name = "A"};
var b = new Item {Name = "B"};
var c = new Item {Name = "C"};

var items = new List<Item>()
{
a,
b,
c,
};

// add B as an alternative to A
a.Alternatives.Add(b);

// that means A is an alternative to B
b.Alternatives.Add(a);

// add C as an alternative to B
b.Alternatives.Add(c);

// that means B is an alternative to C
c.Alternatives.Add(b);

// and now the complication: it means that C is an alternative to A too, because A is alternative to B
a.Alternatives.Add(c);

// and it means A is an alternative to C too
c.Alternatives.Add(a);

// let's print the alternatives
foreach(var item in items)
{
Console.Write($"Item {item.Name} has the alternatives: ");

foreach(var alternative in item.Alternatives)
{
Console.Write($"{alternative.Name} ");
}

Console.WriteLine();
}

// Result:
// Item A has the alternatives: B C
// Item B has the alternatives: A C
// Item C has the alternatives: B A

// then... trying to add/remove numerous alternatives...
// would make all thing way to complicated to sync all item.Alternatives in each
}
}

public class Item
{
public string Name {get; set;}
public List<Item> Alternatives {get; set;} = new();
}
using System;
using System.Collections.Generic;

public class Program
{
public static void Main()
{
// we have 3 items: A, B and C
var a = new Item {Name = "A"};
var b = new Item {Name = "B"};
var c = new Item {Name = "C"};

var items = new List<Item>()
{
a,
b,
c,
};

// add B as an alternative to A
a.Alternatives.Add(b);

// that means A is an alternative to B
b.Alternatives.Add(a);

// add C as an alternative to B
b.Alternatives.Add(c);

// that means B is an alternative to C
c.Alternatives.Add(b);

// and now the complication: it means that C is an alternative to A too, because A is alternative to B
a.Alternatives.Add(c);

// and it means A is an alternative to C too
c.Alternatives.Add(a);

// let's print the alternatives
foreach(var item in items)
{
Console.Write($"Item {item.Name} has the alternatives: ");

foreach(var alternative in item.Alternatives)
{
Console.Write($"{alternative.Name} ");
}

Console.WriteLine();
}

// Result:
// Item A has the alternatives: B C
// Item B has the alternatives: A C
// Item C has the alternatives: B A

// then... trying to add/remove numerous alternatives...
// would make all thing way to complicated to sync all item.Alternatives in each
}
}

public class Item
{
public string Name {get; set;}
public List<Item> Alternatives {get; set;} = new();
}
https://dotnetfiddle.net/rJQSRv
C# Online Compiler | .NET Fiddle
Test your C# code online with .NET Fiddle code editor.
Sygmond
Sygmond4mo ago
This is what it was designed by someone else. I proposed to my PM a simpler solution. Initially I was ignored and now the whole thing got to complicated. Looking forward to see what other people have in mind, without clouding them with my solution.
Joschi
Joschi4mo ago
So alternatives always go both ways?
Sygmond
Sygmond4mo ago
yes
Joschi
Joschi4mo ago
Is the path of interest? What I mean is, do you need to know that A is an alternative to C, because both are an alternative to B?
Sygmond
Sygmond4mo ago
Yes. Each item needs to have complete list of alternatives, so every new alternative item added, the synchronization needs to be done again and add in each item the new alternative
Joschi
Joschi4mo ago
That didn't answer the question. Do you just need to know that A is an alternative to C, or is the information important that A is an alternative to C, because both are alternatives to B. Basically is there a difference between something being a direct alternative or indirect one.
Sygmond
Sygmond4mo ago
No, I just need to know that A is an alternative to C If I add D as alternative to A, D will be alternative to all. Is not important in the UI why. I just need to list/print the alternatives of each. each item has its own tab with a grid where all alternatives for that item is listed
Joschi
Joschi4mo ago
Then what is the problem with stuffing them all into a simple list?
Sygmond
Sygmond4mo ago
like in my example? the problem is if I add D to the list of A, that D needs to be added to the rest of the items.Alternatives you have to check each item where A is an alternative and add D and to D add the item that you just checked
Joschi
Joschi4mo ago
No just have a single list containing A B and C. And if D comes into the mix add it to that single list
Sygmond
Sygmond4mo ago
and each item would have an id that points to that list? what I proposed is grouping, because this is esentially groups
Sygmond
Sygmond4mo ago
C# Online Compiler | .NET Fiddle
Test your C# code online with .NET Fiddle code editor.
Joschi
Joschi4mo ago
Yes you could do that
Sygmond
Sygmond4mo ago
assign a groupId to the ones you want to be alternatives and done
Joschi
Joschi4mo ago
Unless you need to recalculate the groups often that also works fine. (If it's all stored in a DB that's less of a concern)
Sygmond
Sygmond4mo ago
yes, is in the DB, but is loaded in the memory (UI) and if a new item is added in any alternative group, is tracked and saved separately. but with a group or a list like you said, is way simpler than the current implementation
Want results from more Discord servers?
Add your server