Avatar billede bongo7 Praktikant
15. april 2010 - 17:07 Der er 24 kommentarer og
1 løsning

forslag til løsning

Ja ved ikke lige hvad jeg skulle kalde dette emne,

men leder efter en måde at gribe det an på når jeg skal lave en funktion der gør således og ved ikke hvordan det kan lade sig gøre da jeg er ny i det her.


Skal lave en funktion der modtager et integer og sætter det i en liste med andre numre som man kan søge i MEN , meningen er så at det sidst ankomme nummer så skal være "låst" og ignores i de næste 3 sekunder og derefter frigives så man kan arbejde med numemret igen og der så nok er kommet et nyt nummer imellemtiden som også er låst i 3 sekunder osv osv.

dvs nummer 3 kommer ind i listen, låses i 3 sekunder, nummer 11 kommer ind og låses i 3 sekunder  de føste 3 sekunder er gået og nr 3 frigives i listen.. osv osv

er der nogle der har en ide om hvordan den her kan løses. jeg er helt blank for ideer
Avatar billede janus_007 Nybegynder
15. april 2010 - 20:00 #1
Giv dit nummer et datetimestamp, noget ala:

public class SomeNumber
{
public int Number{get;set;}
public DateTime InsertTime {get; private set; }
}


IList<SomeNumber> so = new List<SomeNumber>();
public class SomeOtherClassForLogic
{

public AddNumber(int number)
{
so.Add(new SomeObject{number, DateTime.Now)
}
}
public IEnumerable<SomeNumber> GetNumbers()
{
return so.Where(x => x.InsertTime < DateTime.Now.AddSeconds(-3));
}

Ikke testet.. bare lige skrevet, men noget i den stil :)
Avatar billede bongo7 Praktikant
15. april 2010 - 20:15 #2
har fundet ud af at lave en masse timer der aktiveres og deaktiveres , problem løst
Avatar billede arne_v Ekspert
15. april 2010 - 20:18 #3
Janus's loesning er bedre end timere.

Jeg var naaet frem til naesten den samme loesning:

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

namespace E
{
    public class Entry<T>
    {
        public DateTime TimeStamp { get; set; }
        public T Value { get; set; }
    }
    public class DelayedContainer<T>
    {
        private List<Entry<T>> data = new List<Entry<T>>();
        public void Add(T o)
        {
            data.Add(new Entry<T>{TimeStamp = DateTime.Now, Value = o});
        }
        public List<T> GetList()
        {
            DateTime cut = DateTime.Now.AddSeconds(-3);
            return data.Where(e => e.TimeStamp < cut).Select(e => e.Value).ToList();
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            DelayedContainer<int> lst = new DelayedContainer<int>();
            for(int i = 1; i <= 10; i++)
            {
                lst.Add(i);
                Console.WriteLine("Adding " + i);
                foreach(int v in lst.GetList()) Console.Write(" " + v);
                Console.WriteLine();
                Thread.Sleep(1000);
            }
            Thread.Sleep(3000);
            Console.WriteLine("Done");
            foreach(int v in lst.GetList()) Console.Write(" " + v);
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}
Avatar billede bongo7 Praktikant
15. april 2010 - 20:20 #4
ser intrersant ud, kigger lige på det,

vil lige høre din menning om at LINQ  er det ikke en langsom funktion at bruge hvis det skal gå stærkt ???  kender ikke performance på brugen af LinQ
Avatar billede arne_v Ekspert
15. april 2010 - 20:30 #5
For at vurdere effektiviteten af LINQ skal du kigge paa hvad den faktisk laver.

Jeg vil gaette paa at min kode vil tage:

<100 milliardetedele sekunder for Add

antal elementer * <100 milliardetedele sekunder for GetList

Er der nogen grund til at optimere det?

Hvis du bruger LINQ to SQL eller LINQ to EF, saa sker der naturligvis en del mere.
Avatar billede bongo7 Praktikant
15. april 2010 - 21:21 #6
okey arne der fik du vist gjort det klart at der skal meget til før man skal tale om hastighed tak, troede bare det var en sløv banan at bruge linq generelt , tak



ARNE..  tænkte på om man kan gøre så den ikke skriver dobbelt. hvis man gør    lst.Add(i) i dit eksempel vil eksempelvis have to gange nummer 12 hvis jeg forstår det rigtigt, kan man gøre så den opdater timestamp hvis den eksistere i forvejen
Avatar billede janus_007 Nybegynder
15. april 2010 - 21:22 #7
Ja sådan kan man også sige det som Arne gjorde :), men nej... du behøver slet ikke bekymre dig om performance på Linq - det er ammestuesnak fra folk der ikke ved bedre.
Det er klart der er et overhead ved de delegates/ expressions der bruges i Linq, men det bliver formodentligt interessant når du arbejder med 1.000.000.000 objekter og så har du noget andet at tænke på end performance alligevel :)
Avatar billede arne_v Ekspert
15. april 2010 - 21:45 #8
Hvis du vil overskrive elementer som allerede er der, saa skal du nok skifte fra List<> til HashSet<> og have Equals og HashCode i Entry klassen.
Avatar billede bongo7 Praktikant
15. april 2010 - 21:55 #9
say what ?

den forstod jeg ikke,

altså du vil have denne således.
private HashSet<Entry<T>> data = new HashSet<Entry<T>>();

og ændre denne til dette ???

public class Entry<T>
    {
     
        public DateTime TimeStamp { get; set; }
        public T Value { get; set; }
        public Equals { get; set; }
        public HashCode { get; set; }
    }




men hvordan skal den ændres,
Avatar billede bongo7 Praktikant
15. april 2010 - 21:57 #10
hovsa således


public DateTime TimeStamp { get; set; }
        public T Value { get; set; }
        public T Equals { get; set; }
        public T HashCode { get; set; }
Avatar billede arne_v Ekspert
15. april 2010 - 22:13 #11
Eksempel:

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

namespace E
{
    public class DelayedContainer<T>
    {
        private class Entry<U>
        {
            public DateTime TimeStamp { get; set; }
            public U Value { get; set; }
            public override bool Equals(object obj)
            {
                if(obj is Entry<U>)
                    return Value.Equals(((Entry<U>)obj).Value);
                else
                    return false;
            }
            public override int GetHashCode()
            {
                return Value.GetHashCode();
            }
        }
        private HashSet<Entry<T>> data = new HashSet<Entry<T>>();
        public void Add(T o)
        {
            Entry<T> ent = new Entry<T>{TimeStamp = DateTime.Now, Value = o};
            if(!data.Add(ent))
                data.Where(e => e.Equals(ent)).First().TimeStamp = ent.TimeStamp;
        }
        public IList<T> GetList()
        {
            DateTime cut = DateTime.Now.AddSeconds(-3);
            return data.Where(e => e.TimeStamp < cut).Select(e => e.Value).ToList();
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            DelayedContainer<int> lst = new DelayedContainer<int>();
            for(int i = 1; i <= 10; i++)
            {
                lst.Add((i-1)%5+1);
                Console.WriteLine("Adding " + ((i-1)%5+1));
                foreach(int v in lst.GetList()) Console.Write(" " + v);
                Console.WriteLine();
                Thread.Sleep(1000);
            }
            Thread.Sleep(3000);
            Console.WriteLine("Done");
            foreach(int v in lst.GetList()) Console.Write(" " + v);
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}
Avatar billede arne_v Ekspert
15. april 2010 - 22:14 #12
Jeg er dog ikke helt tilfreds med Add metoden.
Avatar billede arne_v Ekspert
15. april 2010 - 22:17 #13
Maaske var det alligevel paenere at skifte til en Dictionary<T,DateTime>.
Avatar billede arne_v Ekspert
15. april 2010 - 22:21 #14
Jep.

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

namespace E
{
    public class DelayedContainer<T>
    {
        private IDictionary<T, DateTime> data = new Dictionary<T, DateTime>();
        public void Add(T o)
        {
            if(data.ContainsKey(o))
                data[o] = DateTime.Now;
            else
                data.Add(o, DateTime.Now);
        }
        public IList<T> GetList()
        {
            DateTime cut = DateTime.Now.AddSeconds(-3);
            return data.Where(e => e.Value < cut).Select(e => e.Key).ToList();
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            DelayedContainer<int> lst = new DelayedContainer<int>();
            for(int i = 1; i <= 10; i++)
            {
                lst.Add((i-1)%5+1);
                Console.WriteLine("Adding " + ((i-1)%5+1));
                foreach(int v in lst.GetList()) Console.Write(" " + v);
                Console.WriteLine();
                Thread.Sleep(1000);
            }
            Thread.Sleep(3000);
            Console.WriteLine("Done");
            foreach(int v in lst.GetList()) Console.Write(" " + v);
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}
Avatar billede bongo7 Praktikant
15. april 2010 - 22:29 #15
ja jeg fatter ikke engang hvordan den bruges endnu, kæmper med at læse den igen og igen. forstår ikke hvor den opdatere det nummer der netop er kommet ind i listen og lader de andre være uændret

læser lige igen
Avatar billede bongo7 Praktikant
15. april 2010 - 22:31 #16
ahhh nu dæmrer der noget,  MEN forstår stadigt ikke hvor du indsætter en post to gange *G* *G*

output ser korrekt ud og ja det er sgo pæn kode af hvad jeg trods alt kan se
Avatar billede arne_v Ekspert
15. april 2010 - 22:34 #17
ved at indsaette (i-1)%5+1 fremfor i opnaar jeg at indsaette 1..5 to gange i.s.f. 1..10 en enkelt gang
Avatar billede bongo7 Praktikant
15. april 2010 - 22:35 #18
nej forstår sim,pelthen ikke hvad du gør her

lst.Add((i - 1) % 5 + 1);


det der forvirre mig  , hvorfor alle de tal ((i - 1) % 5 + 1);

hvad gør de ?? :)
Avatar billede bongo7 Praktikant
15. april 2010 - 22:37 #19
arhh tusind tak, det hjalp en smule på forståelsen. skal lige læse den et par gange mere kan godt se hvad du mener skal bare lige have det stykket sammen i hovedet nu
Avatar billede arne_v Ekspert
15. april 2010 - 22:40 #20
Nu er den del af koden jo kun for test og saaledes ikke saa relevant.

Men logikkekn er:

i        i-1        (i-1)%5          (i-1)%5+1
1        0            0                  1
2        1            1                  2
3        2            2                  3
4        3            3                  4
5        4            4                  5
6        5            0                  1
7        6            1                  2
8        7            2                  3
9        8            3                  4
10        9            4                  5

Og der er ikke noget magisk ved den sidste kolonne. Det var bare de tal jeg ville teste med. Og jeg gad ikke skrive 10 linier med hver sin .Add!
Avatar billede bongo7 Praktikant
15. april 2010 - 23:20 #21
lyset gik lige op for mig. HA hvor smart.
Avatar billede bongo7 Praktikant
17. april 2010 - 00:00 #22
hvis jeg nu vil vende lidt op på "suspend" funktionen kan det så passe jeg skal gøre således for at se poster der ikke er låst


public IList<T> GetListNotSuspended()
          {
              DateTime cut = DateTime.Now.AddSeconds(-3);
              return data.Where(e => e.Value < cut).Select(e => e.Key).ToList();
          }
Avatar billede arne_v Ekspert
17. april 2010 - 00:08 #23
Øh. Jeg kan ikke lige se forskellen. Har du ikke kun ændret metodenavnet?
Avatar billede arne_v Ekspert
13. juni 2010 - 04:44 #24
Tid at få afsluttet her?
Avatar billede arne_v Ekspert
19. oktober 2011 - 14:27 #25
Naa - du troede ikke paa de alternative loesninger??
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