Laden...

Vergleich von Objekten

Erstellt von McSteel vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.921 Views
M
McSteel Themenstarter:in
43 Beiträge seit 2008
vor 15 Jahren
Vergleich von Objekten

Hallo,

ich versuche seit gestern ein Vergleich durchzuführen. Leider komme ich irgenwie nicht weiter. Brauche eure Hilfe.

  • Es sind zwei unterschiedlich Listen(Stapel1, Stapel2) mit verschieden Objekten vorhanden
  • Ein Stapel besteht aus mehreren unterschiedlichen Blöcken von Typ.C zu Typ.C.
  • Blöcke können fehlen
  • Alle Objekte müssen in einem Block(z.B Value.A3) eines Stapels aus mit der andern Block aus dem Anderem Stapel verglichen werden.

Meine Versuche sind gescheitert. Lösungsansätze waren jedem Typ eine Position im Stapel zu vegeben und anhand dieser zu Vergleichen aber das klappt nicht...

Das ist die Klasse der Objekte:


using System;
using System.Collections.Generic;
using System.Text;

namespace CompareObjects
{
    public class aObjects
    {
        public Typ Typ;
        public Value Value;
        public int CompareID = -1;

        public aObjects(Typ typ, Value value)
        {
            this.Typ = typ;
            this.Value = value;
        }

        public string Name
        {
            get { return Typ.ToString() + "." + Value.ToString(); }
        }

    }

    public enum Typ {C, T}

    //Die Aufzählöungen haben andere Werte
    public enum Value{A1 = 1234, A2 = 1321, A3 = 1234, A4 = 1123, E1=1121, E2=2123, E3=3242, E4=4563, E5=5638, E6=6523, E7=7829, E8=8367, E9=9232} // und etliche weitere.....


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace CompareObjects
{
    public partial class Form1 : Form
    {
        private List<aObjects> Stapel1 = new List<aObjects>();
        private List<aObjects> Stapel2 = new List<aObjects>();

        string strTemp = string.Empty;
        public Form1()
        {
            InitializeComponent();

            FillTheObjects();
        }

        public void FillTheObjects()
        {
            Stapel1.Add(new aObjects(Typ.C, Value.A1));
            Stapel1.Add(new aObjects(Typ.T, Value.E1));
            Stapel1.Add(new aObjects(Typ.T, Value.E2));
            Stapel1.Add(new aObjects(Typ.T, Value.E4));
            Stapel1.Add(new aObjects(Typ.T, Value.E6));
            Stapel1.Add(new aObjects(Typ.T, Value.E8));
            Stapel1.Add(new aObjects(Typ.C, Value.A2));
            Stapel1.Add(new aObjects(Typ.T, Value.E6));
            Stapel1.Add(new aObjects(Typ.T, Value.E4));
            Stapel1.Add(new aObjects(Typ.T, Value.E4));
            Stapel1.Add(new aObjects(Typ.T, Value.E9));
            Stapel1.Add(new aObjects(Typ.C, Value.A4));
            Stapel1.Add(new aObjects(Typ.T, Value.E1));
            Stapel1.Add(new aObjects(Typ.T, Value.E1));
            Stapel1.Add(new aObjects(Typ.T, Value.E1));
            Stapel1.Add(new aObjects(Typ.T, Value.E9));

            Stapel2.Add(new aObjects(Typ.C, Value.A1));
            Stapel2.Add(new aObjects(Typ.T, Value.E1));
            Stapel2.Add(new aObjects(Typ.T, Value.E2));
            Stapel2.Add(new aObjects(Typ.T, Value.E4));
            Stapel2.Add(new aObjects(Typ.T, Value.E6));
            Stapel2.Add(new aObjects(Typ.T, Value.E4));
            Stapel2.Add(new aObjects(Typ.T, Value.E8));
            Stapel2.Add(new aObjects(Typ.C, Value.A2));
            Stapel2.Add(new aObjects(Typ.T, Value.E6));
            Stapel2.Add(new aObjects(Typ.T, Value.E4));
            Stapel2.Add(new aObjects(Typ.T, Value.E4));
            Stapel2.Add(new aObjects(Typ.C, Value.A3));
            Stapel2.Add(new aObjects(Typ.T, Value.E6));
            Stapel2.Add(new aObjects(Typ.T, Value.E4));
            Stapel2.Add(new aObjects(Typ.T, Value.E4));
            Stapel2.Add(new aObjects(Typ.T, Value.E9));
            Stapel2.Add(new aObjects(Typ.C, Value.A4));
            Stapel2.Add(new aObjects(Typ.T, Value.E1));
            Stapel2.Add(new aObjects(Typ.T, Value.E1));
            Stapel2.Add(new aObjects(Typ.T, Value.E1));
        }

        public int Compare(aObjects x, aObjects y)
        {
            if (x.Name == y.Name)
                return 0;
            else
                return 1;
        }

        private void btnCompare_Click(object sender, EventArgs e)
        {
            foreach (aObjects x in Stapel1)
            {
                strTemp = "";
                foreach (aObjects y in Stapel2)
                {
                        //.... hier fehlt mir der code
                            x.CompareID = Compare(x, y);
                            y.CompareID = Compare(x, y);
                            if (x.CompareID == 0)
                            {
                                strTemp =  x.Name + " = " + y.Name;
                            }
                            else if (x.CompareID = 1)
                            {
                                strTemp = y.Name + " ist in Stapel 1 nicht vorhanden";
                            }
                            else if (y.CompareID = 1)
                            {
                                strTemp = x.Name + " ist in Stapel 2 nicht vorhanden";
                            }
                        //.... hier fehlt mir der code
                       Console.WriteLine(strTemp);
                }
            }
        }
    }
}

Dieser Stream soll am Ende als Text Form ausgegeben werden

Stapel1 = Stapel2

C.A1 = C.A1
T.E1 = T.E1
T.E2 = T.E2
T.E4 = T.E4
T.E6 = T.E6
T.E4 ist in Stapel 1 nicht vorhanden
T.E8 = T.E8

C.A2 = C.A2
T.E6 = T.E6
T.E4 = T.E4
T.E4 = T.E4
T.E9 in Stapel 2 nicht vorhanden

C.A3 in Stapel 1 nicht vorhanden
T.E6 in Stapel 1 nicht vorhanden
T.E4 in Stapel 1 nicht vorhanden
T.E4 in Stapel 1 nicht vorhanden
T.E9 in Stapel 1 nicht vorhanden

C.A4 = C.A4
T.E1 = T.E1
T.E1 = T.E1
T.E1 = T.E1
T.E9 in Stapel 2 nicht vorhanden

Ich danke im voraus für jeden Tipp!!!
steel

T
708 Beiträge seit 2008
vor 15 Jahren

Ich würde das ganz anders und vor allem nicht so kompliziert machen.

Es gibt in Listen z.B. die Funktion Contains()

Sprich:

foreach (aObjects y in Stapel2)
        {
		if(Stapel1.Contains(y))
			strTemp =  x.Name + " = " + y.Name;
		else
			strTemp = y.Name + " ist in Stapel 1 nicht vorhanden";
	}

Damit sparst du dir schonmal ein paar Funktionen und Zeilen.
Natürlich musst du das ein bisschen umbauen um zu schauen welche Daten in welchem Stapel nicht vorhanden sind.

Du könntest natürlich die Ergebnisse erstmal ein einer 3. List zwischenspeichern, doppelte Einträge löschen, sortieren und dann ausgeben.

296 Beiträge seit 2007
vor 15 Jahren

Nene...


foreach (aObjects y in Stapel2)
      (Stapel1.Contains(y))

wird immer false zurückgeben

Was genau meinst du mit Blöcken und was möchtest du genau vergleichen?

Ich steig bei der Frage nicht so ganz durch 🙂 ... haste vll bisschen umständlichen beschrieben. - wenns geht nochmal etwas einfacher bitte.

Gelöschter Account
vor 15 Jahren

contains würde in diesem fall immer "false" zurückgeben, da hier referenzen verglichen werden und wen nich mir die befüllung der beiden listen ansehe dann sind keine objekte doppelt vorhanden, sondern haben nur unter umständen gleiche inhalte.

ich würde am objekt, das verglichen werden soll die IComparable schnittstelle implementieren und dann mit 2 foreach durch beide listen rattern und vergleichen.

M
McSteel Themenstarter:in
43 Beiträge seit 2008
vor 15 Jahren

@trib: Mit deinem sample klappt es nicht

Was genau meinst du mit Blöcken und was möchtest du genau vergleichen?

//Block Anfang
C.A1 = C.A1 //-> Block Anfang kennzeichnet sich mit Typ.C
T.E1 = T.E1
T.E2 = T.E2
T.E4 = T.E4
T.E6 = T.E6
X.XX = T.E4 => in Stapel 1 nicht vorhanden
T.E8 = T.E8
// Block Ende -> kennzeichnet sich durch das leere Ende oder ein Typ.C

//Block Anfang
C.A2 = C.A2
T.E6 = T.E6
T.E4 = T.E4
T.E4 = T.E4
T.E9 = X.XX => in Stappel 2 nich vorhanden
//Block Ende

//Block Anfang => Block mit C.A3 fehlt in Stapel 1
X.XX = C.A3 => in Stapel 1 nicht vorhanden
X.XX = T.E6 => in Stapel 1 nicht vorhanden
X.XX = T.E4 => in Stapel 1 nicht vorhanden
X.XX = T.E4 => in Stapel 1 nicht vorhanden
X.XX = T.E9 => in Stapel 1 nicht vorhanden
//Block Ende

//Block Anfang
C.A4 = C.A4
T.E1 = T.E1
T.E1 = T.E1
T.E1 = T.E1
T.E9 = X.XX =>in Stapel 2 nicht vorhanden
//Block Ende

Ich steig bei der Frage nicht so ganz durch 🙂 ... haste vll bisschen umständlichen beschrieben. - wenns geht nochmal etwas einfacher bitte.

Mache ich gerne.
1.) Es sollen Blöcke aus den Listen(Stapel 1 & 2) rausgefiltert werden.
2.) Anhand des Blockanfangs kann man den Block auch im anderen Stapel finden
3.a) Blöcke in den Stapel sollen verglichen werden,
3.b) Fehlende Blöcke in den Stapel darstelle, wenn C.A3 nicht auffindbar, diese als nicht vorhanden darstellen in der Liste, wo es fehlt.
4.a) Objekte in den Blöcken sollen nach der Filterung der Blöcke verglichen werden
4.b) Fehlende Objekte in Blöcken darstellen
5.) Alles soll in einem "strukturierten" Text in einer Log Datei abgespeichert werden
6.) In zwei Treeviews soll nach dem Vergleich alle Objekte gegenüber aufglistet werden und die fehlenden Objekten gekennzeichnet werden

M
McSteel Themenstarter:in
43 Beiträge seit 2008
vor 15 Jahren

Hat einer eine Ideee?

Gelöschter Account
vor 15 Jahren

wenn du alle meine beiträge nicht liest kann ich dir auch nciht helfen.

691 Beiträge seit 2007
vor 15 Jahren

Moin. Ohne jetz auf die genannten Lösungsvorschlage mit dem Compare einzugehen, wieso verwendest du Zuweisungen statt Vergleiche?


                            if (x.CompareID == 0)
                            {
                                strTemp =  x.Name + " = " + y.Name;
                            }
                            else if (x.CompareID = 1)
                            {
                                strTemp = y.Name + " ist in Stapel 1 nicht vorhanden";
                            }
                            else if (y.CompareID = 1)
                            {
                                strTemp = x.Name + " ist in Stapel 2 nicht vorhanden";
                            }

Nicht lieber so?


                            if (x.CompareID == 0)
                            {
                                strTemp =  x.Name + " = " + y.Name;
                            }
                            else if (x.CompareID == 1)
                            {
                                strTemp = y.Name + " ist in Stapel 1 nicht vorhanden";
                            }
                            else if (y.CompareID == 1)
                            {
                                strTemp = x.Name + " ist in Stapel 2 nicht vorhanden";
                            }

mit freundlichen Grüßen,
Tomot

Projekte: www.gesellschaftsspieler-gesucht.de

M
McSteel Themenstarter:in
43 Beiträge seit 2008
vor 15 Jahren

Ich würde am objekt, das verglichen werden soll die IComparable schnittstelle implementieren und dann mit 2 foreach durch beide listen rattern und vergleichen.

@JAck30lena: Ich habe es noch nie mit IComparable gemacht. Ich wüsste an dieser Stelle nicht was und wie ich es machen sollte.

@Tomot:
Danke, waren Tippfehler von mir.

Gelöschter Account
vor 15 Jahren

dann schaut man normalerweise auf msdn nach denn da findet man erklärung und beispiele.

M
McSteel Themenstarter:in
43 Beiträge seit 2008
vor 15 Jahren

Ich habe mir dieser Beispiel http://msdn.microsoft.com/de-de/library/system.icomparable.compareto(VS.80).aspx, soweit bin ich ja schon.

Leider weiß ich nicht, wie ich sie richtig anwenden soll :< (i'm dau)

Gelöschter Account
vor 15 Jahren

naja ich würde an deiner stelle in diesem konkreten fall lieber IComparable<aObjects> verwenden. so erlaubst du das typisierte vergleichen.

Leider weiß ich nicht, wie ich sie richtig anwenden soll :< (i'm dau)

keine schande über unwissen jedoch musst du schon sagen wo du probleme hast, damit ich dir weiterhelfen kann. eine ausimplementierte lösung könnte ich dir geben. mach ich aber nicht.

gerade IComparable<t> sollte man verinnerlichen, da man das durchaus öfter gebrauchen kann.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo McSteel,

Leider weiß ich nicht, wie ich sie richtig anwenden soll

das selbst herauszufinden, ist allerdings genau deine Aufgabe.

(i'm dau)

wenn du unsere Antworten oder die Doku nicht verstehst, weil dir noch die Grundlagen fehlen, ist das schon ok. Nur erwarten wir dann von dir, dass du dir diese Grundlagen erstmal selbst aneignest. Ein Forum kann das nicht leisten. Siehe [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

herbivore

M
McSteel Themenstarter:in
43 Beiträge seit 2008
vor 15 Jahren

Hallo McSteel,
wenn du unsere Antworten oder die Doku nicht verstehst, weil dir noch die Grundlagen fehlen, ist das schon ok. Nur erwarten wir dann von dir, dass du dir diese Grundlagen erstmal selbst aneignest.

Tue ich das nicht, woher willst du wissen, dass ich mir sie nicht angeeignet habe?!

Hinweise zur Programmierung eines mehrdimensinonalen Liste wären hilfreicher gewesen. Im MSDN und in diesem Forum habe ich leider zu meinem speziellen Thema nichts gefunden.

Ein Forum kann das nicht leisten. Siehe
>
Punkt 1.1.1.
herbivore

Kenne ich schon! Zu Punkt 1.1.1. ist deine Definition des Forums. Der Punkt 1.1.2 fehlt: Was sind Grundlagen?

Sorry wir hatten schonmal diesbezüglich ein Diskussion mit Dir im Forum. Aber ich möchte hier mit dir drüber nicht diskutieren.

M
McSteel Themenstarter:in
43 Beiträge seit 2008
vor 15 Jahren

Ich bin soweit, dass ich zwei Methoden erstellt habe, in welchen die Objekte Block und aObjects verglichen werden und die Werte 0 und 1 zu dem Eigenschaft CompareID übergeben werden.

Definition von CompareID:
0 = Objekt ist in der anderen Liste vorhanden
1 = Objekt ist in der anderen Liste nicht vorhanden

Was mir nun fehlt ist, dass dies als TextStream und in einem TreeView dargestellt wird?


        public void CompareBlock(Block a, Block b)
        {
            if (a.blockType.Name == b.blockType.Name)
            {
                int count = 0;
                if (b.List.Count > a.List.Count)
                {
                    count = b.List.Count;
                }
                else
                {
                    count = a.List.Count;
                }
                for (int i = 0; i < count; i++)
                {
                    if (i > a.List.Count-1)
                    {
                        b.List[i].CompareID = 1;
                        continue;
                    }
                    if (i > b.List.Count-1)
                    {
                        a.List[i].CompareID = 1;
                        continue;
                    }
                    if (a.List[i].Name == b.List[i].Name)
                    {
                        a.List[i].CompareID = 0;
                        b.List[i].CompareID = 0;
                    }
                    else
                    {
                        a.List[i].CompareID = 1;
                        b.List[i].CompareID = 1;
                    }
                }
            }
        }

        public void CompareBlockList(List<Block> a, List<Block> b)
        {
            bool found = false;
            int count = 0;
            if (b.Count > a.Count)
            {
                count = b.Count;
            }
            else
            {
                count = a.Count;
            }
            for (int i = 0; i < a.Count; i++)
            {
                found = false;
                for (int j = 0; j < b.Count; j++)
                {
                    if (a[i].blockType.Name == b[j].blockType.Name)
                    {
                        found = true;
                        CompareBlock(a[i], b[j]);
                        a[i].CompareID = 0;
                        b[j].CompareID = 0;
                    }
                }
                if(! found)
                {
                    a[i].CompareID = 1;
                }            
            }
        }

        private void btnCompare_Click(object sender, EventArgs e)
        {
                BlocklistStapel1.Clear();
                BlocklistStapel2.Clear();
                strTemp = "";
                Value currentBlock = Value.NULL;
                int blockIndex = 0;
                bool blockFound = false;
                //int currentIndex = 0;

                Block b = null;
                foreach (aObjects y in Stapel1)
                {
                    if (y.Typ == Typ.C)
                    {
                        if (b != null)
                            BlocklistStapel1.Add(b);
                        b = new Block();
                        b.blockType = y;
                        blockIndex = 0;
                    }
                    if (y.Typ != Typ.C)
                    {
                        b.List.Add(y);
                        blockIndex++;
                    }
                }
                if (b != null)
                    BlocklistStapel1.Add(b);

                b = null;

                foreach (aObjects y in Stapel2)
                {
                    if (y.Typ == Typ.C)
                    {
                        if (b != null)
                            BlocklistStapel2.Add(b);
                        b = new Block();
                        b.blockType = y;
                        blockIndex = 0;
                    }
                    if (y.Typ != Typ.C)
                    {
                        b.List.Add(y);
                        blockIndex++;
                    }
                }
                if (b != null)
                    BlocklistStapel2.Add(b);

                CompareBlockList(BlocklistStapel1, BlocklistStapel2);
                CompareBlockList(BlocklistStapel2, BlocklistStapel1);
           }

Gelöschter Account
vor 15 Jahren

Der Punkt 1.1.2 fehlt: Was sind Grundlagen?

alles was du im openbook oder in guide to c# findest.

ansonsten gild das was ich schreibe. wenn du ein konkretes problem hast beim implementieren und verwenden von IComparable<t> dann helfe ich dir natürlich gerne weiter aber einfach nur zu schreiben das du es nciht verstehst ist nicht ausreichend.

Hinweise zur Programmierung eines mehrdimensinonalen Liste wären hilfreicher gewesen

das nützt dir hier nichts. deswegen auch kein hinweis hierzu.

den weg über compareid´s würde ich nciht gehen. der ist badstyle in diesem fall, da es ncihts mit einer id (identification) zu tun hat. stattdessen empfiehlt sich ein bool oder enum.

so wie du das hier gemcht hast ist es ein workaround. das ist nur eine anmerkung an diejenigen, die diesen thread irgendwann mal finden und der meinung sind das das der weg ist den man geht. wenn du damit zufrieden bisst dann ist das somit für dich zwar gelöst aber wehe es kommt mal ein codereview^^

M
McSteel Themenstarter:in
43 Beiträge seit 2008
vor 15 Jahren

Der Punkt 1.1.2 fehlt: Was sind Grundlagen?
alles was du im openbook oder in guide to c# findest.

ansonsten gild das was ich schreibe. wenn du ein konkretes problem hast beim implementieren und verwenden von IComparable<t> dann helfe ich dir natürlich gerne weiter aber einfach nur zu schreiben das du es nciht verstehst ist nicht ausreichend.

Es geht wahrscheinlich nicht mit IComparable<T> sondern mit IComparer<T>, da man bei dieser Aufgabe Objekte und Listen vergleichen muss.
CodeReview für alle anderen:


public class BlockComparer: IComparer<Block>{
        public List<aObjects> List = new List<aObjects>();
        public aObjects blockType;
        public Compare CValue;

        public Compare CompareBlock(Block x, Block y)
        {
            if(x.aObjects.Name == y.aObjects.Name)
                CValue = Compare.TRUE;
            else
                CValue = Compare.FALSE;
        }
}

public class aObjectsComparer: IComparer<aObjects>{
        //...
        public Compare CValue;

        public Compare CompareAObjects(aObjects x, aObjects y)
        {
            if(x.Name == y.Name)
                CValue = Compare.TRUE;
            else
                CValue = Compare.FALSE;
        }
}

enum Compare
{
   TRUE,
   FALSE
}

und wie verwende ich den???!!!

Hinweise zur Programmierung eines mehrdimensinonalen Liste wären hilfreicher gewesen
das nützt dir hier nichts. deswegen auch kein hinweis hierzu.

den weg über compareid´s würde ich nciht gehen. der ist badstyle in diesem fall, da es ncihts mit einer id (identification) zu tun hat. stattdessen empfiehlt sich ein bool oder enum.

SIR ja SIR, wie befohlen, siehe oberen C# Code

so wie du das hier gemacht hast ist es ein workaround. das ist nur eine anmerkung an diejenigen, die diesen thread irgendwann mal finden und der meinung sind das das der weg ist den man geht. wenn du damit zufrieden bisst dann ist das somit für dich zwar gelöst aber wehe es kommt mal ein codereview^^

Nunja zufrieden nicht, aber die Funktion ist damit fürs erste erfüllt.

Gelöschter Account
vor 15 Jahren

Es geht wahrscheinlich nicht mit IComparable<T> sondern mit IComparer<T>, da man bei dieser Aufgabe Objekte und Listen vergleichen muss.

wenn ich schreibe IComparable<T> dann meine ich es auch so und nciht anders. IComparer<T> braucht man z.b. um listen nach eigens definierten vorlagen sortieren zu lassen. für deinen fall ist IComparer<T> vollkommend falsch und unbrauchbar.

du vergleichst objekte auf gleichheit oder ungleichheit und da implementiert man direkt am objekt IComparable<T>, damit einem das objekt selber sagen kann ob es mit dem übergbenen objekt gleich oder ungleich ist.