Avatar billede notes2c Nybegynder
25. november 2008 - 18:56 Der er 11 kommentarer og
2 løsninger

Find delta mellem to lister

Hvis jeg har to lister, så kunne jeg godt tænke mig at finde ud af følgende:

1) Hvad er blevet slette fra listen.
2) Hvad er blevet tilføjet til listen.
3) Hvad har ændret sig i listen.

Senariet er:

Jeg starter med at hente alt, ind i liste1, dernæst henter jeg igen alt ind i liste2. Nu vil jeg gerne opdatere liste1 med de ændringer der er mellem liste1 og liste2, altså slette alt det i liste1 som ikke er i liste2. Tilføje alt fra liste2 som ikke er i liste1. Og tilsidst opdatere liste1 med de ændringer som er i liste2.

Er der nogen som har et godt bud.

Det skulle kunne anvendes på generiske lister
Avatar billede kalp Novice
25. november 2008 - 19:02 #1
med andre ord... du vil gerne synkronisere de 2 lister?
Avatar billede kalp Novice
25. november 2008 - 19:03 #2
det er nemt nok, at tjekke på om objekter findes i begge lister og hvis ikke overføre objekter..

men når du snakker ændringer så er det vel fordi du vil have man også tjekker objekternes værdier?
Avatar billede arne_v Ekspert
25. november 2008 - 19:23 #3
Til inspiration:

using System;
using System.Linq;
using System.Collections.Generic;

namespace E
{
    public class Data : IComparable<Data>
    {
        public int Iv { get; set; }
        public string Sv { get; set; }
        public override bool Equals(object obj)
        {
            if(obj is Data)
            {
                return Iv == ((Data)obj).Iv;
            }
            else
            {
                return false;
            }
        }
        public override int GetHashCode()
        {
            return Iv.GetHashCode();
        }
        public override string ToString()
        {
            return "[" + Iv + "," + Sv + "]";
        }
        public int CompareTo(Data d)
        {
            return Iv - d.Iv;
        }
       
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            List<Data> before = new List<Data>();
            before.Add(new Data { Iv=1, Sv="A" });
            before.Add(new Data { Iv=2, Sv="BB" });
            before.Add(new Data { Iv=3, Sv="CCC" });
            List<Data>after = new List<Data>();
            after.Add(new Data { Iv=1, Sv="A" });
            after.Add(new Data { Iv=3, Sv="C--" });
            after.Add(new Data { Iv=4, Sv="DDDD" });
            List<Data> add = after.FindAll(d => !before.Contains(d));
            foreach(Data d in add)
            {
                Console.WriteLine("Added " + d);
            }
            List<Data> del = before.FindAll(d => !after.Contains(d));
            foreach(Data d in del)
            {
                Console.WriteLine("Deleted " + d);
            }
            before.Sort();
            after.Sort();
            int ixbef = 0;
            int ixaft = 0;
            while(ixbef < before.Count || ixaft < after.Count)
            {
                if(ixbef >= before.Count)
                {
                    Console.WriteLine("Added " + after[ixaft]);
                    ixaft++;
                }
                else if(ixaft >= after.Count)
                {
                    Console.WriteLine("Deleted " + before[ixbef]);
                    ixbef++;
                }
                else if(before[ixbef].Iv < after[ixaft].Iv)
                {
                    Console.WriteLine("Deleted " + before[ixbef]);
                    ixbef++;
                }
                else if(before[ixbef].Iv > after[ixaft].Iv)
                {
                    Console.WriteLine("Added " + after[ixaft]);
                    ixaft++;
                }
                else
                {
                    if(before[ixbef].Sv == after[ixaft].Sv)
                    {
                        Console.WriteLine("Unchanged " + before[ixbef]);
                    }
                    else
                    {
                        Console.WriteLine("Changed " + before[ixbef] + " -> " + after[ixaft]);
                    }
                    ixbef++;
                    ixaft++;
                }
            }
            Console.ReadKey();
        }
    }
}
Avatar billede notes2c Nybegynder
25. november 2008 - 20:04 #4
arne_v >> Vil lige prøve eksemplet... Men glemte vist lige at sige at det skulle virke på framwork 2.0...

Men kan jo prøve om jeg kan få det til at virke.
Avatar billede notes2c Nybegynder
25. november 2008 - 20:05 #5
klap >> Du har ret, jeg vil præcis holde to lister i sync...
Avatar billede arne_v Ekspert
25. november 2008 - 20:15 #6
Eksemplet skal konverters en lilel smule for at virke paa 2.0.
Avatar billede arne_v Ekspert
25. november 2008 - 20:23 #7
2.0 syntax:

using System;
using System.Collections.Generic;

namespace E
{
    public class Data : IComparable<Data>
    {
        private int iv;
        private string sv;
        public int Iv { get { return iv; } set { iv = value;} }
        public string Sv { get { return sv; } set { sv = value; } }
        public Data(int iv, string sv)
        {
            this.iv = iv;
            this.sv = sv;
        }
        public override bool Equals(object obj)
        {
            if(obj is Data)
            {
                return Iv == ((Data)obj).Iv;
            }
            else
            {
                return false;
            }
        }
        public override int GetHashCode()
        {
            return Iv.GetHashCode();
        }
        public override string ToString()
        {
            return "[" + Iv + "," + Sv + "]";
        }
        public int CompareTo(Data d)
        {
            return Iv - d.Iv;
        }
       
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            List<Data> before = new List<Data>();
            before.Add(new Data(1, "A"));
            before.Add(new Data(2, "BB"));
            before.Add(new Data(3, "CCC"));
            List<Data>after = new List<Data>();
            after.Add(new Data(1, "A"));
            after.Add(new Data(3, "C--"));
            after.Add(new Data(4, "DDDD"));
            List<Data> add = after.FindAll(delegate (Data d) { return !before.Contains(d); });
            foreach(Data d in add)
            {
                Console.WriteLine("Added " + d);
            }
            List<Data> del = before.FindAll(delegate(Data d) { return !after.Contains(d); });
            foreach(Data d in del)
            {
                Console.WriteLine("Deleted " + d);
            }
            before.Sort();
            after.Sort();
            int ixbef = 0;
            int ixaft = 0;
            while(ixbef < before.Count || ixaft < after.Count)
            {
                if(ixbef >= before.Count)
                {
                    Console.WriteLine("Added " + after[ixaft]);
                    ixaft++;
                }
                else if(ixaft >= after.Count)
                {
                    Console.WriteLine("Deleted " + before[ixbef]);
                    ixbef++;
                }
                else if(before[ixbef].Iv < after[ixaft].Iv)
                {
                    Console.WriteLine("Deleted " + before[ixbef]);
                    ixbef++;
                }
                else if(before[ixbef].Iv > after[ixaft].Iv)
                {
                    Console.WriteLine("Added " + after[ixaft]);
                    ixaft++;
                }
                else
                {
                    if(before[ixbef].Sv == after[ixaft].Sv)
                    {
                        Console.WriteLine("Unchanged " + before[ixbef]);
                    }
                    else
                    {
                        Console.WriteLine("Changed " + before[ixbef] + " -> " + after[ixaft]);
                    }
                    ixbef++;
                    ixaft++;
                }
            }
            Console.ReadKey();
        }
    }
}
Avatar billede kalp Novice
25. november 2008 - 20:38 #8
Du kan også gøre det sådan her.

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


namespace ConsoleApplication3 {
    class Program {
        public Program() {
            List<Something> list1 = new List<Something>();
            Something somethingOne = new Something();
            somethingOne.Firstname = "first";
            somethingOne.Lastname  = "kalp";
            list1.Add(somethingOne);
            somethingOne = new Something();
            somethingOne.Firstname = "last";
            somethingOne.Lastname = "kalp";
            list1.Add(somethingOne);
            somethingOne = new Something();
            somethingOne.Firstname = "funny";
            somethingOne.Lastname = ".net";
            list1.Add(somethingOne);

            List<Something> list2 = new List<Something>();
            somethingOne = new Something();
            somethingOne.Firstname = "first";
            somethingOne.Lastname = "kalp";
            list2.Add(somethingOne);
            somethingOne = new Something();
            somethingOne.Firstname = "test";
            somethingOne.Lastname = "test";
            list2.Add(somethingOne);
            somethingOne = new Something();
            somethingOne.Firstname = "funny";
            somethingOne.Lastname = ".net";
            list2.Add(somethingOne);


            List<Something> list3 = new List<Something>();

            foreach (Something something in list1) {
                if (!list3.Contains(something))
                    list3.Add(something);
            }

            foreach (Something something in list2) {
                if (!list3.Contains(something))
                    list3.Add(something);
            }


        }
        static void Main(string[] args) {
            new Program();
        }
        public class Something {
            public string Firstname;
            public string Lastname;
            public override string ToString() {
                return string.Format("{0} {1}", Firstname, Lastname);
            }
            public override bool Equals(object obj) {
                Something parameter = obj as Something;
                if (parameter.Firstname.ToLower() == Firstname.ToLower()
                  && parameter.Lastname.ToLower() == Lastname.ToLower()) return true;
                return false;
            }
            public override int GetHashCode() {
                string hashcode = Firstname.ToLower() + Lastname.ToLower();
                return hashcode.GetHashCode();
            }
        }
    }
}
Avatar billede kalp Novice
25. november 2008 - 20:42 #9
Min kode består af følgende dele.

1.  public class Something {
            public string Firstname;
            public string Lastname;
            public override string ToString() {
                return string.Format("{0} {1}", Firstname, Lastname);
            }
            public override bool Equals(object obj) {
                Something parameter = obj as Something;
                if (parameter.Firstname.ToLower() == Firstname.ToLower()
                  && parameter.Lastname.ToLower() == Lastname.ToLower()) return true;
                return false;
            }
            public override int GetHashCode() {
                string hashcode = Firstname.ToLower() + Lastname.ToLower();
                return hashcode.GetHashCode();
            }
        }
forklaring: det objekt jeg vil have i min liste. Jeg overrider Equals og GetHashCode så det er muligt og se hvis et objekt findes i en liste via. ".Contains"


2.
List<Something> list1 = new List<Something>();
List<Something> list2 = new List<Something>();
List<Something> list3 = new List<Something>();

forklaring: de 3 lister jeg benytter. Liste 1 og Liste 2 er dem med dine data. Liste3 er den som vil merge de 2.


3.
foreach (Something something in list1) {
                if (!list3.Contains(something))
                    list3.Add(something);
            }

            foreach (Something something in list2) {
                if (!list3.Contains(something))
                    list3.Add(something);
            }

forklaring her synkroniseres listerne

4. (koden her manglede før)

list1.Clear();
            list2.Clear();

            foreach (Something something in list3) {
                list1.Add(something);
                list2.Add(something);
            }


og dermed har du 2 synkroniserede lister.
Avatar billede notes2c Nybegynder
25. november 2008 - 21:05 #10
klap >> Din løsning virker ikke lige helt.

arne_v >> Jeg vil bruge din løsning som inspiration, så smid et svar.

Kan være jeg vender tilbage med et tillægs spm.

Og mange tak for jeres gode input.
Avatar billede notes2c Nybegynder
25. november 2008 - 21:08 #11
klap >> Havde ikke lige set din sidste post. Du kan jo også godt smide et svar, så kan i få en deler.
Avatar billede arne_v Ekspert
25. november 2008 - 21:22 #12
svar
Avatar billede kalp Novice
25. november 2008 - 21:39 #13
=)
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