Hallo,
Ich habe ein Problem bei der Implementierung eines Vergleich zweier Listen.
Ich wäre für jede Hilfe dankbar.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace CompareList
{
public partial class Form1 : Form
{
List<Item> aItems = new List<Item>();
List<Item> bItems = new List<Item>();
public Form1()
{
InitializeComponent();
}
private void btnAddList_Click(object sender, EventArgs e)
{
//..... Durch eine andere Funktion werden beide Listen wie folgt befüllt...
// 1. Liste
Item aItem = new Item();
aItems.Add(aItem);
aItem.Id = 0;
aItem.Name = "Marc";
aItems.Add(aItem);
aItem.Id = 1;
aItem.Name = "Dani";
aItems.Add(aItem);
aItem.Id = 2;
aItem.Name = "Mike";
aItems.Add(aItem);
aItem.Id = 3;
aItem.Name = "Tom";
aItems.Add(aItem);
aItem.Id = 4;
aItem.Name = "Gollum";
// 2.Liste
Item bItem = new Item();
bItems.Add(bItem);
bItem.Id = 0;
bItem.Name = "Marc";
bItems.Add(bItem);
bItem.Id = 1;
bItem.Name = "Dani";
bItems.Add(bItem);
bItem.Id = 2;
bItem.Name = "Hans"; // Name ist Hans
bItems.Add(bItem);
bItem.Id = 3;
bItem.Name = "Sally"; // Name ist Sally
// bItem.Id=4 fehlt
}
private void btnCompare_Click(object sender, EventArgs e)
{
// Definition für die Errors
// aItem.Name == bItem.Name (Item.Error = 0)
// aItem.Name != bItem.Name (Item.Error = 1)
// aItem nicht vorhanden (Item.Error = 2)
// bItem nicht vorhanden (Item.Error = 3)
// gibt es weitere Möglichkeiten??
foreach (Item aItem in aItems)
{
foreach (Item bItem in bItems)
{
if(aItem.Id == bItem.Id)
{
if(aItem.Name == bItem.Name)
{
aItem.Error = 0;
bItem.Error = 0;
}
else if(aItem.Name != bItem.Name)
{
aItem.Error = 1;
bItem.Error = 1;
}
}
else if(aItem.Id != bItem.Id) //hier entsteht ein Fehler bei bItem.Id=4, weil es nicht vorhanden ist , wie könnte man dies umgehen?
{
aItem.Error = 3;
bItem.Error = 3;
}
}
}
}
}
public class Item
{
private int m_Id;
private string m_Name;
private int m_Error;
public int Id
{
get
{
return m_Id;
}
set
{
if (m_Id != value)
{
m_Id = value;
}
}
}
public string Name
{
get
{
return m_Name;
}
set
{
if (m_Name != value)
{
m_Name = value;
}
}
}
public int Error
{
get
{
return m_Error;
}
set
{
if (m_Error != value)
{
m_Error = value;
}
}
}
}
}
1. Googlen 2. Boardsuche benutzen 3. Überlegen 4. Posten
Ich sage es nur äußerst ungerne,aber darf man in Foren/wo auch immer eine klitzekleine Frage stellen,ohne dass gleich ein Oberlehrer mit der obligatorischen "Google suchen"-Antwort kommt?
Hallo SteelWarrior,
wie kann ich vermeiden aItem.Id=1 und bItem.Id=2 zu vergleichen.
gar nicht. Ohne die beiden Items zu vergleichen weißt du ja nicht, dass du sie nicht vergleichen willst. 🙂 Aber es schadet ja nicht, sie zu vergleichen. Wenn man sie nicht beachten will, tut man das eben aufrund des Ergebnis des Vergleich einfach nicht.
An deinem Code unten fehlt doch eigentlich nur noch das
foreach (Item aItem in aItems) {
foreach (Item bItem in bItems) {
// hier dein Vergleichs Code
}
}
herbivore
wie schauts damit aus?
public class Item {
public int Id;
public string Name;
public int Error;
public Item() {
Id = -1;
Name = String.Empty;
Error = -1;
}
}
bool foundId = false; //signalisiert ob ein bItem mit entsprechedner Id gefunden wurde
foreach(Item b in bItems) {
b.Error = -1;
}
foreach(Item a in aItems) {
foundId = false;
foreach(Item b in bItems) {
if(a.Id == b.Id) {
foudId = true;
if(a.Name == b.Name) {
a.Error = 0;
b.Error = 0;
} else {
a.Error = 1;
b.Error = 1;
}
break;
}
}
if(!foundId) {
a.Error = 3;
}
}
foreach(Item b in bItems) {
if(b.Error == -1) {
b.Error = 2;
}
}
kurze erklärung:
also deine klasse item hab ich abgeändert so das error als initialwert -1 is, damit man später sieht ob da schon was geändert wurde
so, also beide leisten werden quasi durchgegangen wobei jedes item aus aItems mit jedem item aus bItems verglichen werden
wenn ein item mit derselben id gefunden wird, wird ein bollsche variable auf true gesetzt
das signalisiert ob es für ein item aus aItems auch ein item aus bItems gab (später wichtig)
vergleich von a und b ist ansonsten gleich wie bei dir geblieben, nur das ich danach die innere schleife abbreche, haben ja unser ergebnis
wenn jedes b aus bItems mit einem a verglichen wurde wird geprüft ob die boolsche variable true oder false is
ist sie false heißt das in bItems haben wir nichts gefunden mit der gleichen id, also setzen wir den errorcode in a auf 3
nachdem jedes item aus aItems abgearbeitet wurde, sollte für jedes item auch ein error code gesetzt sein
in bItems ist für jedes Item ein errorcode gesetzt wo entweder der name gleich war oder unterschiedlich, d.h. alle restlichen haben kein entsprechendes item in aItems
daher die 2. schleife die alle items in bItems durchgeht und prüft ob errorcode -1 is (der initialwert) und dafür dann eine 2 einträgt (a in aItems nicht vorhanden)
nachtrag:
da wir den errorcode von einem Item in bItems als indikator benutzen sollte nwir ihn vor dem ganzen geprüfe auc hwieder zurück setzn auf -1
is halt bissl unschön das wir 2x zusätzlich durch bItems durchlaufen müßen, aber wüßte jetzt auch nicht wie man das eleganter lösen könnten
nachtrag 2:
andere lösung die mir grad einfällt wäre das hier
Dictionary<int, Item> dic = new Dictionary<int, Item>(aItems.Length);
foreach(Item a in aItems) {
a.Error = 3;
dic.Add(a.Id,a);
}
foreach(Item b in bItems) {
Item a = null;
dic.TryGetValue(b.Id,out a);
if(a != null) {
if(a.Name == b.Name) {
a.Error = 0;
b.Error = 0;
} else {
a.Error = 1;
b.Error = 1;
}
} else {
b.Error = 2;
}
}
wäre, schätz ich mal, halt bissl schneller, aber verbrauch bissl mehr speicherplatz
dafür mußt du deine klasse nicht anpassen 🙂
nachtrag: von hashtable auf dictionary umgestellt
Danke sheitman,
die erste Lösung hat mir weitergeholfen 🙂
1. Googlen 2. Boardsuche benutzen 3. Überlegen 4. Posten
Ich sage es nur äußerst ungerne,aber darf man in Foren/wo auch immer eine klitzekleine Frage stellen,ohne dass gleich ein Oberlehrer mit der obligatorischen "Google suchen"-Antwort kommt?