Avatar billede juks Novice
29. januar 2008 - 16:02 Der er 25 kommentarer og
1 løsning

Sortering af arralist

hej
Jeg skal sortere en tabel der inde holder Cprnr ,serienr, score
resultat er så
2501801111,1,24
2501801111,2,32
2501801111,3,28
osv.
men jeg ville gerne have den til at gøre sådan her .

2501801111,24,28,32
så man kun får listet cprnr  også scorene for en given konkurrence.
hvordan gør man det nemmest.


NB min AccessDataReader returnere som skrvet ovenfor
2501801111,1,24
2501801111,2,32
2501801111,3,28


ArrayList List = DataAccessWrite.reader("Select cprnr,serienr,score From Serie_tbl WHERE KonID = " + DataAccessWrite.PubString2);
            for (int i = 0; i < List.Count; i++)
            {
                List.Sort(new MyComparer());
                this.listBox1.Items.Add(List[i]);
            }
Avatar billede powerpunk Nybegynder
29. januar 2008 - 16:17 #1
Igen er du jo lidt på spanden fordi du ikke bruger en rigtig datahåndteringsklasse...

Hvad med:

ArrayList List = DataAccessWrite.reader("Select cprnr,serienr,score From Serie_tbl WHERE KonID = " + DataAccessWrite.PubString2);

List.Sort();

string currentValue ="";
string lastCpr = ""
for(int i = 0; i< List.Count; i++)
{
  string[] t = List[i].Split(',');
  if(lastCpr != "" && lastCpr != t[0])
    lastCpr = currentValue = t[0];
  else if (lastCpr = t[0])
    currentValue += "," + t[2];
  else
  {
    this.listBox1.Items.Add(currentValue);
    lastCpr = t[0];
    currentValue += "," + t[2];
  }
}
Avatar billede powerpunk Nybegynder
29. januar 2008 - 16:20 #2
Det gik lidt for stærkt...

string currentValue ="";
string lastCpr = null;
for(int i = 0; i< List.Count; i++)
{
  string[] t = List[i].Split(','); //Split

  if(lastCpr != null) //Hvis sidste CPR ikke er sat:
    lastCpr = currentValue = t[0]; //Sæt aktivt CPR.
    currentValue += "," + t[2]; //Tilføj score
  else if (lastCpr = t[0]) //Hvis sidste CPR er sat men = det aktive.
    currentValue += "," + t[2]; //Tilføj score
  else //Hvis CPR er sat men forskelligt fra det aktive.
  {
    this.listBox1.Items.Add(currentValue); //Skriv den genererede streng til liste.
    lastCpr = t[0]; //Sæt nyt aktivt CPR
    currentValue += "," + t[2]; //Tilføj score
  }
}
Avatar billede arne_v Ekspert
29. januar 2008 - 16:21 #3
Du sorterer saa du har data som beskrevet ovenfor.

Saa fixer du det naar du bruger data a la foelgende pseudo code:

            old = -1;
            temp = "";
            for (int i = 0; i < List.Count; i++)
            {
                n1 = first column
                n2 = second column
                n3 = third column
                if(n1 != old)
                {
                    if(temp != "") this.listBox1.Items.Add(temp);
                    temp = n1 + "," + n3
                }
                else
                {
                    temp + "," + n3
                }
            }
Avatar billede juks Novice
29. januar 2008 - 16:26 #4
hehe du fik mig... næste år laver jeg den med list<>


men den var næsten perfekt din kode

    ArrayList List = DataAccessWrite.reader("Select cprnr,serienr,score From Serie_tbl WHERE KonID = " + DataAccessWrite.PubString2);

            List.Sort(new MyComparer());

                                string currentValue ="";
                                string lastCpr = "";
                                for(int i = 0; i< List.Count; i++)
                                {
                                    string[] t = List[i].ToString().Split(',');
                                  if(lastCpr != "" && lastCpr != t[0])
                                    lastCpr = currentValue = t[0];
                                  else if (lastCpr == t[0])
                                    currentValue += "," + t[2];
                                  else
                                  {
                                   
                                    lastCpr = t[0];
                                    currentValue += "," + t[2];
                                  }
                                }
                              this.listBox1.Items.Add(lastCpr + currentValue);
Avatar billede juks Novice
29. januar 2008 - 16:35 #5
hmm
den nye kode du skrev powerpunk..
kan jeg ikke få til at skrive noget



            ArrayList List = DataAccessWrite.reader("Select cprnr,serienr,score From Serie_tbl WHERE KonID = " + DataAccessWrite.PubString2);

            List.Sort(new MyComparer());

            string currentValue = "";
            string lastCpr = null;
            for (int i = 0; i < List.Count; i++)
            {
                string[] t = List[i].ToString().Split(','); //Split

                if (lastCpr != null) //Hvis sidste CPR ikke er sat:
                {
                    lastCpr = currentValue = t[0]; //Sæt aktivt CPR.
                    currentValue += "," + t[2]; //Tilføj score
                }
                else if (lastCpr == t[0]) //Hvis sidste CPR er sat men = det aktive.
                {
                    currentValue += "," + t[2]; //Tilføj score
                }
                else //Hvis CPR er sat men forskelligt fra det aktive.
                {
                    this.listBox1.Items.Add(currentValue);
                    //Skriv den genererede streng til liste.
                    lastCpr = t[0]; //Sæt nyt aktivt CPR
                    currentValue += "," + t[2]; //Tilføj score
                }

            }
Avatar billede juks Novice
29. januar 2008 - 16:53 #6
mn der kan jo godt komme et nyt cprnr .

så listen kommer til at se sådan ud ...
240101000,1,24
240101000,2,27
240101000,3,24
888888888,1,78
888888888,2,41
888888888,3,77
Avatar billede juks Novice
29. januar 2008 - 17:08 #7
men skal jo ende med at se sådan her ud

241010000,24,24,27
888888888,41,77,78
Avatar billede juks Novice
29. januar 2008 - 17:08 #8
men jeg kan ikke få jeres forslag til at virke.
Avatar billede powerpunk Nybegynder
29. januar 2008 - 17:32 #9
Doh!

  if (lastCpr != null) //Hvis sidste CPR ikke er sat:

skal selvfølgelig være

  if (lastCpr == null) //Hvis sidste CPR ikke er sat:
Avatar billede arne_v Ekspert
29. januar 2008 - 17:35 #10
using System;
using System.Collections;

namespace E
{
    public class MainClass
    {
        public static void Main(string[] args)
        {
            ArrayList lst = new ArrayList();
            lst.Add("240101000,1,24");
            lst.Add("240101000,2,27");
            lst.Add("240101000,3,24");
            lst.Add("888888888,1,78");
            lst.Add("888888888,2,41");
            lst.Add("888888888,3,77");
            int old = -1;
            string temp = "";
            for (int i = 0; i < lst.Count; i++)
            {
                string[] parts = ((string)lst[i]).Split(",".ToCharArray());
                int n1 = int.Parse(parts[0]);
                int n2 = int.Parse(parts[1]);
                int n3 = int.Parse(parts[2]);
                if(n1 != old)
                {
                    if(temp != "") Console.WriteLine(temp);
                    temp = n1 + "," + n3;
                    old = n1;
                }
                else
                {
                    temp = temp + "," + n3;
                }
            }
            if(temp != "") Console.WriteLine(temp);
        }
    }
}

udskriver:

240101000,24,27,24
888888888,78,41,77

(jeg mangler sortering, men det forstaar jeg at der er styr paa)
Avatar billede powerpunk Nybegynder
29. januar 2008 - 17:36 #11
(blindkode er noget farligt stads...)
Avatar billede powerpunk Nybegynder
29. januar 2008 - 17:58 #12
Arne_v's kode er lidt pænere end min hvad angår logikken i for-loopet: dog synes jeg et par ændringer ville være på sin plads:

for (int i = 0; i < lst.Count; i++)
{
  string[] parts = ((string)lst[i]).Split(','); //Ingen grund til at konverter string til char array, når der kun skal bruges en char...
                //heller ingen grund til først at caste til int for så at lave en streng igen...
                if(parts[0] != old)
                {
                    if(temp != "")
                      this.listBox1.Items.Add(temp);
                    temp = parts[0] + "," + parts[2];
                    old = parts[0];
                }
                else
                {
                    temp = temp + "," + parts[2];
                }
            }
Avatar billede juks Novice
30. januar 2008 - 00:44 #13
nu har jeg prøvet 100 gange , får stadig kun en linje

        private void rangliste_show_Load(object sender, EventArgs e)
        {

            ArrayList List = DataAccessWrite.reader("Select cprnr,serienr,score From Serie_tbl WHERE KonID = " + DataAccessWrite.PubString2);

          // List.Sort(new MyComparer());
            Int64 old = -1;
            string temp = "";
            for (int i = 0; i < List.Count; i++)
            {
                string[] parts = ((string)List[i]).Split(",".ToCharArray());
                Int64 n1 = Int64.Parse(parts[0]);
                int n2 = int.Parse(parts[1]);
                int n3 = int.Parse(parts[2]);
                if (n1 != old)
                {
                    if (temp != "") Console.WriteLine(temp);
                    temp = n1 + "," + n3;
                    old = n1;
                }
                else
                {
                    temp = temp + "," + n3;
                }
            }
              if (temp != "") this.listBox1.Items.Add(temp); //Console.WriteLine(temp);
             
        }
Avatar billede arne_v Ekspert
30. januar 2008 - 00:50 #14
if (temp != "") Console.WriteLine(temp);
...
if (temp != "") this.listBox1.Items.Add(temp); //Console.WriteLine(temp);

du udskriver en til console og gemmer en i listbox - er det med vilje ?
Avatar billede juks Novice
30. januar 2008 - 00:52 #15
ahh nej j
Avatar billede juks Novice
30. januar 2008 - 00:55 #16
self ...  Det er så smukt. synes i skal dele .. tusind tak for hjælpen ...
Avatar billede juks Novice
30. januar 2008 - 01:20 #17
hmm nu sortere den så ikke på scoren ...
Avatar billede powerpunk Nybegynder
30. januar 2008 - 08:13 #18
Nej det er nok svært at komme udenom

Men det ville da også være nemmest at lave den sortering i dit dataudtræk:

"Select cprnr,serienr,score From Serie_tbl WHERE KonID = " + DataAccessWrite.PubString2 + " ORDER BY CprNr, score"
Avatar billede powerpunk Nybegynder
30. januar 2008 - 08:14 #19
svar!, forresten ;-)
Avatar billede juks Novice
30. januar 2008 - 09:12 #20
men jeg ville gerne kunne sortere og ligge de bedste øverst ..

DVs måske gøre det via den liste jeg har gennereret ..

jeg har lavet en compare funktion tidligere men ved ikke helt hvordan ejg får den listen ind i denn
Avatar billede powerpunk Nybegynder
30. januar 2008 - 09:47 #21
Der er vi jo så tilbage i at en liste ikke er så godt gearet til datamanipulation.

Sortering af data er afgjort nemmest enten i dataudtrækket eller ved brug af en eller anden data-klasse f.eks DataSet/DataTable/DataView, alternativt nogle hjemmebryggede objects og en comparer.

Eksempelvis kunne du lave et object der indeholdt cprnummer og en liste af scores. Objektet bruger IComparable for at kunne sammenligne sig med andre Players f.eks:

    public class Player : IComparable<Player>
    {
        private string _cpr;
        private readonly List<int> _scores = new List<int>();

        public ReadOnlyCollection<int> Scores
        {
            get { return _scores.AsReadOnly(); }
        }

        public int MaxScore
        {
            get { return _scores[_scores.Count - 1]; }
        }

        public string Cpr
        {
            get { return _cpr; }
        }

        public Player(string cpr)
        {
            _cpr = cpr;
        }

        public void AddScore(int score)
        {
            _scores.Add(score);
            _scores.Sort();
            _scores.Reverse();
        }

        public override string ToString()
        {
            string temp = _cpr;
            foreach (int i in _scores)
                temp += "," + i;
            return temp;
        }

        #region IComparable<Player> Members

        public int CompareTo(Player other)
        {
            return MaxScore.CompareTo(other.MaxScore);
        }

        #endregion
    }
Avatar billede powerpunk Nybegynder
30. januar 2008 - 09:48 #22
programkoden kunne så være sådan her:

            string[] lst = new string[]
            {
                "240101000,1,24",
                "240101000,2,27",
                "240101000,3,24",
                "888888888,1,78",
                "888888888,2,41",
                "888888888,3,77"
            };

            string old = "";
            List<Player> players = new List<Player>();
            Player temp = null;

            foreach (string s in lst)
            {
                string[] parts = s.Split(',');
                string cpr = parts[0];
                int score = int.Parse(parts[2]);

                if (cpr != old)
                {
                    temp = new Player(cpr);
                    players.Add(temp);
                    temp.AddScore(score);
                    old = cpr;
                }
                else
                {
                    temp.AddScore(score);
                }
            }
            players.Sort(); //Sorter
            players.Reverse(); //Reverse, da vi vil have spiller med højeste score først...

            foreach (Player p in players)
                Console.WriteLine(p);
Avatar billede powerpunk Nybegynder
30. januar 2008 - 09:50 #23
output er:

888888888,78,77,41
240101000,27,24,24
Avatar billede juks Novice
30. januar 2008 - 09:57 #24
ja problemet er jo så at den sortere på cpr nummer også. og ville jeg jo helst ikke..

måske hvis jeg læste det hele  ind i et nyt array og så sorteret på det .
vha

class MyComparer : IComparer
    {
        //Vi opretter en region vi vil arbejde med
        #region IComparer Members     

        public int Compare(object x, object y)
        {
            string xStr = x as string;
            string yStr = y as string;

            string[] xArr = xStr.Split(',');
            string[] yArr = yStr.Split(',');

            string xLast = xArr[xArr.Length - 1];
            string yLast = yArr[yArr.Length - 1];

            int xScore = int.Parse(xLast);
            int yScore = int.Parse(yLast);

            return -xScore.CompareTo(yScore);  //Resultat bliver returneret

        }
men så er det jo igen problemet med cprnr
Avatar billede juks Novice
30. januar 2008 - 10:07 #25
ahh nu jeg ser.. når jeg nok ikke denne gang ..
Avatar billede powerpunk Nybegynder
30. januar 2008 - 10:18 #26
Du kan jo bare undlade:
            players.Sort();
            players.Reverse();

Men du er nødt til som minimum at have grupperet dit dataudtræk så ens cpr-numre kommer i rigtig rækkefølge.

hvis du undlader de to ovenstående linjer er resultatet

output er:

240101000,27,24,24
888888888,78,77,41
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester