Laden...

Wenn eine kopierte List<int> sortiert wird, wird auch die originale sortiert

Erstellt von Smoo vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.498 Views
S
Smoo Themenstarter:in
2 Beiträge seit 2018
vor 5 Jahren
Wenn eine kopierte List<int> sortiert wird, wird auch die originale sortiert

Hallo Welt!

Ich habe da so eine List bestehend aus genau 6 int. Nun möchte ich in Erfahrung bringen, ob da mind. 2 werte ≥ 15 sind.
Da ich die Reihenfolge aber nicht durcheinander bringen will, habe ich mir gedacht, machst du dir noch eine zusätzliche Liste und füllst sie mit der 1. ab. Diese kann ich dann gefahrenlos sortieren und da ich weiss, dass es immer 6 Zahlen sind, muss ich nur schauen ob die 5. ≥ 15 ist und schon weiss ich, was ich wissen will. So weit so gut.

Wenn ich nun aber diese 2. Liste sortiere, zeigt mir der Debugger an, dass auch die 1. Liste sortiert worden ist. Somit stimmen meine Zahlen nicht mehr überein und alles ist für die Katz.

Warum tut der das?!


private List<int> value = new List<int>(); 
private List<int> kevin = new List<int>(); 

value = newRoll.RollDiceGen((int)DiceRule.Free);                                   


            tb_Strength.Text = value[0].ToString();
            tb_Dexterity.Text = value[1].ToString();
            tb_Constituition.Text = value[2].ToString();
            tb_Intelligence.Text = value[3].ToString();
            tb_Wisdom.Text = value[4].ToString();
            tb_Charisma.Text = value[5].ToString();

            if (cBox_DiceRule.SelectedIndex == (int)DiceRule.Kevin)
            {
                kevin = value;

                kevin.Sort(); 
                if(kevin[4] < 15)
                {
                    KevinRule();
                }
                else
                {
                    MessageBox.Show("2 values higher or equal 15 achieved!");
                }
            }

16.842 Beiträge seit 2008
vor 5 Jahren

Klassicher Fehler von Referenz- vs. Werte-Typen in .NET
Value Types and Reference Types

Mit

kevin = value;

machst Du nicht anderes, als dass beide Listen auf den gleichen Speicher zeigen und damit natürlich auch inhaltlich völlig identisch sind.
Was Du machen willst ist eine Listen-Kopie, zB mit

kevin = value.ToList();

Im Falle von Listen mit Werte-Typen wie int zeigen beide Listen dann auch wie gewünscht auf verschiedene Referenzen.

C
2.122 Beiträge seit 2010
vor 5 Jahren

Für diese Aufgabe ist es übrigens nicht nötig die Liste zu sortieren. Es geht schneller sie zu durchlaufen und zu zählen wie viele Einträge größer als 15 sind.

P
64 Beiträge seit 2011
vor 5 Jahren

Moin

du kannst auch einfach LINQ benutzen. Dann schrumpft das ganze zu einem Einzeiler


  var count = kevin.where( x => x>=15 ).Count();   

M
368 Beiträge seit 2006
vor 5 Jahren

Neben LINQ wird vermutlich eine elementare(re) Herangehensweise verlangt:


...
using System.Collections.Generic;
...
namespace Sort_and_Examine_List_via_LINQ
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> numbers = new List<int>();
            numbers.Add(4);
            numbers.Add(0);
            numbers.Add(10);
            numbers.Add(50);
            numbers.Add(1000);
            numbers.Add(40);

// LINQ-Query
// int count = numbers.Where(x => x >= 15).Count();
            // Console.WriteLine(count);

           int zaehler = 0;
            foreach (var result in numbers)
            {
                if (result > 15)
                    zaehler += 1;
                
            }
            Console.WriteLine("Menge an Zahlen grösser als 15 : " + zaehler);
            Console.ReadLine();
        }
    }
}

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

S
Smoo Themenstarter:in
2 Beiträge seit 2018
vor 5 Jahren

Vielen Dank euch allen! Wieder viel gelernt!

T
2.224 Beiträge seit 2008
vor 5 Jahren

Eine weitere Lösung öhne LINQ wäre auch ein FindAll gewesen, was dann innerhalb der List<T> über die Liste per foreach läuft.
Dann bekommst du ebenfalls eine Liste mit der du dann auch per Count die Anzahl der Elemente bekommst.

Ist zwar das gleiche wie von M.L. aber eben schon mit Bordmitteln der List<T> gelöst.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

A
764 Beiträge seit 2007
vor 5 Jahren
  
  var count = kevin.where( x => x>=15 ).Count();     
  

Oder auch so:

var countDiceRollsGreater14 = diceRolls.Count(diceRoll => diceRoll > 14);

Zum Code selber noch ein paar Worte:

  
private List<int> value = new List<int>();  
//'value' als Variablen-Name besser nicht verwenden, weil es ein C#-Keyword ist.  
  
private List<int> kevin = new List<int>();   
  
value = newRoll.RollDiceGen((int)DiceRule.Free);                                     
  
  
            tb_Strength.Text = value[0].ToString();  
            tb_Dexterity.Text = value[1].ToString();  
            tb_Constituition.Text = value[2].ToString();  
            tb_Intelligence.Text = value[3].ToString();  
            tb_Wisdom.Text = value[4].ToString();  
            tb_Charisma.Text = value[5].ToString();  
  
            if (cBox_DiceRule.SelectedIndex == (int)DiceRule.Kevin)  
            {  
// DiceRule.Kevin -> Kevin scheint also ein bestimmter Modus zu sein  
// Die Liste heißt aber auch kevin. Das ist etwas verwirrend.  
                kevin = value;  
  
                kevin.Sort();   
                if(kevin[4] < 15)  
                {  
// Und was macht KevinRule? Ich dachte, das wäre der Modus.  
                    KevinRule();  
                }  
                else  
                {  
                    MessageBox.Show("2 values higher or equal 15 achieved!");  
                }  
            }  
  
C
2.122 Beiträge seit 2010
vor 5 Jahren

Neben LINQ wird vermutlich eine elementare(re) Herangehensweise verlangt

Ja das denke ich auch. Ich frag mich regelmäßig, warum jemand der ganz am Anfang steht und noch nicht weiß was er da überhaupt tut, ein LINQ Statement hingeknallt kriegt und das dann die Hilfe gewesen sein soll.

A
764 Beiträge seit 2007
vor 5 Jahren

Neben LINQ wird vermutlich eine elementare(re) Herangehensweise verlangt
Ja das denke ich auch. Ich frag mich regelmäßig, warum jemand der ganz am Anfang steht und noch nicht weiß was er da überhaupt tut, ein LINQ Statement hingeknallt kriegt und das dann die Hilfe gewesen sein soll.

Ich denke, für Anfänger ist es durchaus interessant zu sehen, wie aus einer vermeintlich komplexen Aufgabe ein gut verständlicher Einzeiler wird.

C
2.122 Beiträge seit 2010
vor 5 Jahren

Als Zusatzinfo natürlich jederzeit. Aber das eigentliche Verständnisproblem sollte man nicht ignorieren.

Ich bin froh dass ich ganz "altmodisch" programmieren gelernt habe. Zunächst ohne Objektorientierung, dafür weiß ich was Pointer sind und wie man C-Style Strings richtig handhabt. Da haben einige gestöhnt warum man das noch braucht, aber ich weiß jetzt wenigstens was ich mache.