0

i had created a c# my class list with three fields. that fields also list namely device id, device mode, time. i had sort my class list with respect to to time. time list is sorted successfully but device mode list is not sorted with respect to time list. how can i achieve it. my sample code i given below.

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

namespace PBAttendance.App_Code
{
    public class DeviceLogData
    {
        List<int> deviceID = new List<int> { };
        List<int> deviceMode = new List<int> { };
        List<DateTime> time = new List<DateTime> { };
        public List<int> DeviceID
        {
            get { return deviceID; }
            set { deviceID = value; }
        }
        public List<int> DeviceMode
        {
            get { return deviceMode; }
            set { deviceMode = value; }
        }
        public List<DateTime> Time
        {
            get { return time; }
            set { time = value; }
        }
    }
}

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

namespace PBAttendance.App_Code
{
    public class DeviceLogDataList:List<DeviceLogData>
    {
    }
}

DeviceLogDataList dvclogDataList = new DeviceLogDataList();
DeviceLogData dvclogData = new DeviceLogData();
dvclogData.DeviceID.Add(1);
dvclogData.DeviceMode.Add(1);
dvclogData.Time.Add(DateTime.ParseExact("10:49", "HH:mm", System.Globalization.CultureInfo.InvariantCulture));
dvclogData.DeviceID.Add(1);
dvclogData.DeviceMode.Add(1);
dvclogData.Time.Add(DateTime.ParseExact("10:49", "HH:mm", System.Globalization.CultureInfo.InvariantCulture));
dvclogData.DeviceID.Add(1);
dvclogData.DeviceMode.Add(2);
dvclogData.Time.Add(DateTime.ParseExact("12:51", "HH:mm", System.Globalization.CultureInfo.InvariantCulture));
dvclogData.DeviceID.Add(1);
dvclogData.DeviceMode.Add(2);
dvclogData.Time.Add(DateTime.ParseExact("09:49", "HH:mm", System.Globalization.CultureInfo.InvariantCulture));
dvclogData.DeviceID.Add(1);
dvclogData.DeviceMode.Add(1);
dvclogData.Time.Add(DateTime.ParseExact("13:49", "HH:mm", System.Globalization.CultureInfo.InvariantCulture));

 dvclogDataList.Add(dvclogData);

dvclogDataList[0].Time.Sort();

The time list is sorted to 09:49,10:49,10:49,12:51,13:49 perfectly but the device mode and device id not sorted with respect to time list. how can achieve this. please help me. sorry for my bad English. thanks in advance.

Siva
  • 259
  • 6
  • 24
  • Are all Lists aspects of the same element. E.g: Is deviceID[0] pointing to the same element as deviceMode[0]. If yes, I would create a base class called device, which contains all you DiviceModes, IDs etc. This list could be sorted easily. It would have the advantage, that nobody can ever "misssort" your data. – Christian Sauer Jul 08 '13 at 13:37
  • Both time and mode, though are the parts of same instance of the class they are altogether different Lists. so I dont think sorting one List will have any affect on other List. – Rakesh Jul 08 '13 at 13:38
  • check this out: http://stackoverflow.com/questions/7099741/c-sharp-list-sort-by-two-columns , http://stackoverflow.com/questions/289010/c-sharp-list-sort-by-x-then-y – Arie Jul 08 '13 at 13:41
  • The question is "Why would it sort your other two lists?" You have 3 lists here, and they are all separate things. Sorting one doesn't and shouldn't have any influence on the other lists. If you want to sort by time, you will have to rethink the way you are storing data. For a fine example of how to do it (that I was just about to start typing up) see Steve B's answer. :) – ZombieSheep Jul 08 '13 at 13:37
  • @ZombieSheep once i stored the data in the list after that i never store any other data.now i sort time list then the other two lists also sorted with respect to time list. – Siva Jul 09 '13 at 05:44

3 Answers3

5

You should create a simple class that holds the data:

public class DeviceLogData {
    public int DeviceID{get; set;}
    public int DeviceMode{get; set;}
    public DateTime Time {get; set;}
}

void Foo(){

    var theList = new List<DeviceLogData>();
    theList.Add(new DeviceLogData{
        DeviceID: 42,
        DeviceMode: 66,
        Time = DateTime.Now
    });

    ...

    var ordered = theList.OrderBy(log=>log.Time);
    foreach(var log in ordered)
    {
          DoSomethingWithLog(log);
    }
}

[edit]

As Servy pointed out, you can also sort the list itself, instead of enumerating its content.

You can use a Comparison:

List<DeviceLogData> theList = new List<DeviceLogData>();
theList.Add(new DeviceLogData{        DeviceID: 42,        DeviceMode: 66,        Time = DateTime.Now    });
theList.Add(new DeviceLogData{        DeviceID: 43,        DeviceMode: 67,        Time = DateTime.Now    });

var comparer = new Comparison<DeviceLogData>( 
   // Use the Time property to compare the custom object
   (log1, log2) => log1.Time.CompareTo(log2.Time)
   );

theList.Sort(comparer);

[end of edit]

The key point is to have related data together within a single object. In comparison, synchronizing the data when it's split across several lists may be challenging.

Extra advice:

You should take a look in the many available generic lists. For example, you can also use a Dictionary<int,DeviceLogData> in order to be able to retrieve the data by Id.

Steve B
  • 36,818
  • 21
  • 101
  • 174
  • Are you talking about `System.Collections.Generic.SortedList`? – Henrik Jul 08 '13 at 13:54
  • It's actually more efficient to add the items to a `List` and then sort it than to add the items to a `SortedList`. `SortedList` is, in most cases, inferior to another collection for any particular task. I've almost never found it to be the best collection for any given job. – Servy Jul 08 '13 at 14:03
  • @Henrik: yeas, I missed the first generic argument. Thanks – Steve B Jul 08 '13 at 14:13
  • @Servy: does it matter? The idea of my answer was to highlight the creation of a custom object. The SortedList is completary to simplify the sorting requirement. Maybe there are faster collections, lower memory consumption collections, etc. But as there is no "realtime" or heavy requirement mentioned, I can live with that. Feel free to add extra link for more advanced users. – Steve B Jul 08 '13 at 14:17
  • @SteveB Well, that and `SortedList` doesn't have a constructor that accepts delegates, so this code won't even work. The point was you went out of your way to change the code the OP was using (which was a list that he called `Sort` on) to a `SortedList`. Just leaving the code that he had, and using a `List`, would be better in quite a number of ways, including, among other things, performance. – Servy Jul 08 '13 at 14:22
  • Hum... I may have confused with another class. Apologize. I've updated the code to answer with something that compiles. – Steve B Jul 08 '13 at 14:47
  • Note that `List.Sort` has an overload that takes a comparer delegate, in the event that mutating the list rather than returning a sorted sequence is needed. – Servy Jul 08 '13 at 15:03
  • @Servy: I added a small code snippet related to your last comment. Feel free to edit the post if I was wrong. – Steve B Jul 08 '13 at 15:37
  • @SteveB i am fully confused. i doesn't change my devicelogdata. i want use as it is. but when i sort the time list then all other list to be sorted with respect to time list. how can i achieve this. can u please help me.. – Siva Jul 09 '13 at 05:41
  • @siva: You may succeed in synchronizing the sort operation by defining a new list of indexes, then reorder all the lists following these indexes. But it will be quite complex, hard to read and high potential of bug. So I highly suggest you to model your data with classes, like I showed in my answer. Do you see anything wrong with my approach? It's true you will have to refactor your code to match the new object model, but I bet this will be far more easier and less risky than continuing in the direction you are talking about. Give a try ;) – Steve B Jul 09 '13 at 07:51
1

You need to link the lists together somehow. Perhaps make a List with a Tuple in it holding your items and then sort on the first field of the tuple.

Alternatively, make a DeviceLogEntry with members Time, DeviceID and DeviceMode.

You apparently want the integrity so model for it.

ranieuwe
  • 2,268
  • 1
  • 24
  • 30
0

Maybe this can help on what you need to accomplish:

    public class DeviceLogData
    {
        private static SortedDictionary<DateTime, string> sorteditems = new SortedDictionary<DateTime, string>();

        public int DeviceID { get; set; }
        public int DeviceMode { get; set; }
        public DateTime Time { get; set; }

        public DeviceLogData(int id,int mode,DateTime dt)
        {
            DeviceID = id;
            DeviceMode = mode;
            Time = dt;
            sorteditems.Add(dt, string.Format("At {0} Device with Id -> {1} and mode -> {2} has logged!", dt, id, mode));
        }

        public static SortedDictionary<DateTime, string> GetRecords()
        {
            return sorteditems;
        }
    }

then to use it you can do this:

            List<DeviceLogData> dlr = new List<DeviceLogData>();
            dlr.Add(new DeviceLogData(1, 1, DateTime.ParseExact("12:51", "HH:mm", System.Globalization.CultureInfo.InvariantCulture)));
            dlr.Add(new DeviceLogData(1, 2, DateTime.ParseExact("10:49", "HH:mm", System.Globalization.CultureInfo.InvariantCulture)));
            dlr.Add(new DeviceLogData(1, 1, DateTime.ParseExact("13:49", "HH:mm", System.Globalization.CultureInfo.InvariantCulture)));
            dlr.Add(new DeviceLogData(1, 1, DateTime.ParseExact("09:49", "HH:mm", System.Globalization.CultureInfo.InvariantCulture)));
            dlr.Add(new DeviceLogData(1, 3, DateTime.ParseExact("09:48", "HH:mm", System.Globalization.CultureInfo.InvariantCulture)));
            dlr.Add(new DeviceLogData(1, 1, DateTime.ParseExact("15:31", "HH:mm", System.Globalization.CultureInfo.InvariantCulture)));

            foreach (var item in DeviceLogData.GetRecords())
            {
                Console.WriteLine(item.Value);
            }

            Console.ReadLine();
terrybozzio
  • 4,424
  • 1
  • 19
  • 25
  • Why extend the list? Just use `List` directly. If you really, really don't want to type out the generic name than you can just use an actual alias rather than inheriting from `List`. – Servy Jul 08 '13 at 15:04
  • yep,was so preocupied with trying not to change is layout that forgot the basic :)thanks. – terrybozzio Jul 08 '13 at 15:24