The idea is that I have an object GrossPanel
that has a property GrossPanel.PanelList
that contains a list of Panel
objects ;List<Panel>
Each Panel
object has the property of type double Panel.Prod_Width
What I want to do is to match each Panel.Prod_Width
in the input
to each Panel.Prod_Width
in the template.PanelList
When a match is found, the Panel
from the input
list is put into a new GrossPanel
object and removed frominput
. If a complete matching set is found the resulting GrossPanel
is added to the _Returnlist
and everyting is repeated until the input
list is exhausted.
Example:
Lets say the input
contains 9 elements (Panel0-Panel8) and template
contains 2 elements (temp0-temp1)
- Panel0-Panel3 has Prod_Width = 200
- Panel4-Panel7 has Prod_Width = 300
- Panel8 has Prod_Width = 400
- temp0 has Prod_Width = 200 and temp1 has Prod_Width = 300
This should create 4 GrossPanel
objects, GP0-GP3
- GP0 should contain Panel0 and Panel4
- GP1 should contain Panel1 and Panel5
- GP2 should contain Panel2 and Panel6
- GP3 should contain Panel3 and Panel7
Panel8 can't be used
This is the code I have written to do this. It works, but it is very slow.
Is there a way to do this more efficient? I tried to do a foreach
loop and removing elements from input
along the way, but it din't work. Instead I use Index
and _index
to skip the "used" elements in input
private static List<GrossPanel> Match (List<Panel> input, GrossPanel template)
{
List<Panel> _template = template.PanelList.OrderBy(panel => panel.Prod_Width).ToList();
List<Panel> _input = input.OrderBy(panel => panel.Prod_Width).ToList();
List<GrossPanel> _Returnlist = new List<GrossPanel>();
List<int> indexlist = new List<int>(); // list of used indexes
int Index = 0; //counting the panels you have checked
while (Index < _input.Count)
{
int _index = 0;
GrossPanel Grosspanel = new GrossPanel();
for (int templateindex = 0; templateindex < _template.Count(); templateindex++)
{
for (int inputindex = _index; inputindex < _input.Count(); inputindex++)
{
if ((!indexlist.Contains(inputindex)) && (_template.ElementAt(templateindex).Prod_Width == _input.ElementAt(inputindex).Prod_Width))
{
indexlist.Add(inputindex);
Grosspanel.AddNetPanel(input.ElementAt(inputindex));
_index = indexlist.Last(); //
Index++;
break;
}
}
}
if (Grosspanel.NetPanelCount == _template.Count()) _Returnlist.Add(Grosspanel);
else if (Grosspanel.NetPanelCount != _template.Count()) Index = _input.Count;
}
return _Returnlist;
}
OK...
I tried to use IEnuberable
and yield return
to make this quicker. My problem now is that when I find a match in input
I can't seem to remove it from input
in the next iteration.
here is the code
private static IEnumerable<GrossSteniPanel> Match (IEnumerable<Panel> input, GrossPanel template, List<Panel> usedpanels, int index)
{
GrossPanel Grosspanel;
List<Panel> _usedpanels = new List<Panel>();
IEnumerable<Panel> _input = input;
_input = _input.Except(usedpanels);
if (index < 0 | (_input.Count() == 0)) yield return Grosspanel = new GrossPanel();
else
{
foreach (Panel p in _input)
{
if (p.Prod_Width == template.NetPanelList.ElementAt(index).Prod_Width)
{
_usedpanels.Add(p);
_input = _input.Except(_usedpanels);
foreach (GrossPanel panel in Match (_input, template, usedpanels, index - 1))
{
Grosspanel = panel;
Grosspanel.AddNetPanel(p);
yield return Grosspanel;
}
}
}
}
}
What am I missing??