Benutzer mit den meisten Antworten
Nicht vorhandenes Element in Tupelliste finden

Frage
-
Hallo Leute. Ich habe zwei Tupellisten
private List<Tuple<Piece, Byte>> actualFigures = new List<Tuple<Piece, byte>>(); private List<Tuple<Piece, Byte>> actualFiguresCopy = new List<Tuple<Piece, byte>>();
Wie finde ich das nicht vorhandene Element von Liste1, verglichen mit Liste2(gerne auch mittels LINQ). Liste1 hat genau 1 Element weniger wie Liste 2. Diese Element(Piece) möchte ich haben. Mit PHP würde ich das mit der Funktion array_diff_assoc() machen. Die gibt es jedoch nicht in C#. Weiß jemand Rat? Bisher versuche ich es so. Das haut aber nicht hin
for (int i = 0; i < actualFigures.Count; i++) { //steige aus, sofern unten ein Element gefunden wurde if (haveLeftLoop) break; for (int j = 0; j < actualFiguresCopy.Count; j++) { if (i == j) { //prüfe, ob die Figuren identisch sind.. sameFigure = actualFigures[i].Item1.Equals(actualFiguresCopy[j].Item1); //..falls nein,verfrachte die gefundene Figur in die Liste der geschlagenen Figuren if (!sameFigure) { figuresBeaten.Add(actualFiguresCopy[i].Item1); haveLeftLoop = true; break; } } } }
- Bearbeitet tklustig Freitag, 26. Juli 2019 18:19
Antworten
-
Das LINQ statement
var result = actualFiguresCopy.Where(x => !actualFigures.Contains(x)).FirstOrDefault();
funktionert wider Erwarten nicht. Obgleich beide Listen identisch sind, liefert result einen Treffer. Unabhängig davon ist der Treffer nie korrekt, liefert also die falsche Figur
Habe das jetzt so gelöst:
for (int i = 0; i < actualFigures.Count; i++) { //steige aus, sofern unten ein Element gefunden wurde if (haveLeftLoop) break; for (int j = 0; j < actualFiguresCopy.Count; j++) { if (i == j) { //prüfe, ob die Figuren identisch sind.. sameFigure = actualFigures[i].Item1.Equals(actualFiguresCopy[j].Item1); //..falls nein,verfrachte die gefundene Figur in die Liste der geschlagenen Figuren if (!sameFigure) { coordinate = this.giveBackCoordinates(figureMovedX, figureMovedY); foreach (var item in actualFiguresCopy) { if (item.Item2 == coordinate) { figuresBeaten.Add(item.Item1); break; } } haveLeftLoop = true; break; } } } }
Hier noch meine Klasse Piece
namespace ChessGUI { #region Enumeration - Figur public enum PieceType { Bauer, Springer, Laeufer, Turm, Dame, Koenig } #endregion #region Enumeration - Farbe public enum PieceColor { Black, White, Dummy } #endregion public class Piece : IPiece { #region globale Variablen private readonly PieceColor _color; private readonly PieceType _type; #endregion #region Standardkonstruktor public Piece() { } #endregion #region Konstruktor - mit Argumenten public Piece(PieceType type, PieceColor color) { _type = type; _color = color; } #endregion #region Getter(ohne Setter) public PieceType Type { get { return _type; } } public PieceColor Color { get { return _color; } } #endregion #region Überschreibt die Methode aus der Klasse Object public override int GetHashCode() { unchecked { return ((int)_color * 397) ^ (int)_type; } } #endregion #region Überschreibt die Methode aus der Klasse Object public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != GetType()) return false; return this.Equals((Piece)obj); } #endregion #region wird von obiger Methode benötigt public bool Equals(Piece figure) { return _color == figure._color && _type == figure._type; } #endregion } }
- Bearbeitet tklustig Samstag, 27. Juli 2019 12:22
- Als Antwort vorgeschlagen Guido Franzke Montag, 29. Juli 2019 06:21
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 5. August 2019 08:47
Alle Antworten
-
Hallo,
hast Du in deiner Klasse Piece die Vergleichsoperatoren implementiert? Ohne diese kannst Du Klassen nicht miteinander vergleichen.
Hier ein einfaches Beispiel ohne Operatoren
class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); Pixel a = new Pixel() { B = 0, G = 0, R = 0 }; Pixel b = new Pixel() { B = 0, G = 0, R = 0 }; if (a == b || a.Equals(b)) { //Wert ist immer false } } } public class Pixel { public byte R { get; set; } public byte G { get; set; } public byte B { get; set; } }
Und hier mit Operatoren
class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); Pixel a = new Pixel() { B = 0, G = 0, R = 0 }; Pixel b = new Pixel() { B = 0, G = 0, R = 0 }; if (a == b || a.Equals(b)) { //Erst jetzt ist ein Vergleich möglich } } } public class Pixel { public byte R { get; set; } public byte G { get; set; } public byte B { get; set; } public override bool Equals(object obj) { if (obj is Pixel p) { return this == p; } return false; } public override int GetHashCode() { return R.GetHashCode() * 5 + G.GetHashCode() * 13 + B.GetHashCode() * 19; } public static bool operator ==(Pixel a, Pixel b) { return a.B == b.B && a.G == b.G && a.R == b.R; } public static bool operator !=(Pixel a, Pixel b) { return a.R != b.R || a.G != b.G || a.B != b.B; } }
Gruß Thomas
13 Millionen Schweine landen jährlich im Müll
Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings- Bearbeitet Thomas Wycichowski Freitag, 26. Juli 2019 22:21
-
Hallo,
hier noch ergänzend mit Linq.
Da ich deine Klasse "Piece" nicht kenne, habe ich hier mal eine Beispielklasse erfunden:
Die erfundene Klasse "Piece":
public class Piece { public int Figur { get; set; } public Point Position { get; set; } public override string ToString() => $"Figur: {Figur}, ; }
Im ersten Teil des Beispiels verwende ich statt "Tuple" eine erweiterte Klasse, auch wenn das jetzt nicht Teil der Frage war:
public class PieceExt : Piece { public byte AnyByte { get; set; } public override string ToString() => $"AnyByte: {AnyByte}, Base: {base.ToString()}"; }
So, hier in der folgenden Methode werden einmal Listen mit "PieceExt" erstellt und per Linq ausgewertet. Darunter dann aber mit List<Tuple...>
public static void Go() { // Mit erfundener Klasse... // Liste 1 var pe1 = new List<PieceExt>() { new PieceExt() { AnyByte= 1, Figur = 1, Position = new Point(1,1) }, new PieceExt() { AnyByte= 2, Figur = 2, Position = new Point(2,2) }, new PieceExt() { AnyByte= 3, Figur = 3, Position = new Point(3,3) }}; // Liste 2 var pe2 = new List<PieceExt>(pe1); pe2.Add(new PieceExt() { AnyByte = 4, Figur = 4, Position = new Point(4, 4) }); // Linq-Abfrage var result = pe2.Where(x => !pe1.Contains(x)).FirstOrDefault(); Console.WriteLine(result.ToString()); Console.ReadKey(); // Mit Tuple-Gedöns var actualFigures = new List<Tuple<Piece, byte>>() { Tuple.Create(new Piece() { Figur = 1, Position = new Point(1,1) }, (byte)1), Tuple.Create(new Piece() { Figur = 2, Position = new Point(2,2) }, (byte)2), Tuple.Create(new Piece() { Figur = 3, Position = new Point(3,3) }, (byte)3)}; var actualFiguresCopy = new List<Tuple<Piece, byte>>(actualFigures); actualFiguresCopy.Add(Tuple.Create(new Piece() { Figur = 4, Position = new Point(4,4) }, (byte)4)); var result2 = actualFiguresCopy.Where(x => !actualFigures.Contains(x)).FirstOrDefault(); Console.WriteLine($"Piece: {result2.Item1.ToString()}, Byte: {result2.Item2} "); Console.ReadKey(); }
Gruß
Nachtrag:
Aus mir unbekanntem Grund wird hier im Codeblock der Klasse Piece in der Methode ToString() "Position..." automatisch beim Speichern/Senden entfernt. Es soll da also stehen:
public override string ToString() => $"Figur: {Figur}, Position: {Position}" ;
- Bearbeitet K. Pater Samstag, 27. Juli 2019 11:05
-
Das LINQ statement
var result = actualFiguresCopy.Where(x => !actualFigures.Contains(x)).FirstOrDefault();
funktionert wider Erwarten nicht. Obgleich beide Listen identisch sind, liefert result einen Treffer. Unabhängig davon ist der Treffer nie korrekt, liefert also die falsche Figur
Habe das jetzt so gelöst:
for (int i = 0; i < actualFigures.Count; i++) { //steige aus, sofern unten ein Element gefunden wurde if (haveLeftLoop) break; for (int j = 0; j < actualFiguresCopy.Count; j++) { if (i == j) { //prüfe, ob die Figuren identisch sind.. sameFigure = actualFigures[i].Item1.Equals(actualFiguresCopy[j].Item1); //..falls nein,verfrachte die gefundene Figur in die Liste der geschlagenen Figuren if (!sameFigure) { coordinate = this.giveBackCoordinates(figureMovedX, figureMovedY); foreach (var item in actualFiguresCopy) { if (item.Item2 == coordinate) { figuresBeaten.Add(item.Item1); break; } } haveLeftLoop = true; break; } } } }
Hier noch meine Klasse Piece
namespace ChessGUI { #region Enumeration - Figur public enum PieceType { Bauer, Springer, Laeufer, Turm, Dame, Koenig } #endregion #region Enumeration - Farbe public enum PieceColor { Black, White, Dummy } #endregion public class Piece : IPiece { #region globale Variablen private readonly PieceColor _color; private readonly PieceType _type; #endregion #region Standardkonstruktor public Piece() { } #endregion #region Konstruktor - mit Argumenten public Piece(PieceType type, PieceColor color) { _type = type; _color = color; } #endregion #region Getter(ohne Setter) public PieceType Type { get { return _type; } } public PieceColor Color { get { return _color; } } #endregion #region Überschreibt die Methode aus der Klasse Object public override int GetHashCode() { unchecked { return ((int)_color * 397) ^ (int)_type; } } #endregion #region Überschreibt die Methode aus der Klasse Object public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != GetType()) return false; return this.Equals((Piece)obj); } #endregion #region wird von obiger Methode benötigt public bool Equals(Piece figure) { return _color == figure._color && _type == figure._type; } #endregion } }
- Bearbeitet tklustig Samstag, 27. Juli 2019 12:22
- Als Antwort vorgeschlagen Guido Franzke Montag, 29. Juli 2019 06:21
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 5. August 2019 08:47
-
Das LINQ statement
var result = actualFiguresCopy.Where(x => !actualFigures.Contains(x)).FirstOrDefault();
funktionert wider Erwarten nicht. Obgleich beide Listen identisch sind, liefert result einen Treffer. Unabhängig davon ist der Treffer nie korrekt, liefert also die falsche Figur
Hi,
das ist eigenartig. Bei funktioniert das jedenfalls auch mit deiner "Piece"-Klasse.
Da du aber eine Lösung gefunden hast, brauchen wir das nicht weiter verfolgen.
Gruß