سؤال

المشكلة الرئيسية:كيف يمكنني عناصر المجموعة قبل التاريخ ، إلا إذا كانت مستمرة إلا إذا كانت تطابق بعض الخصائص ؟

التفاصيل:

وبالنظر إلى هذا النوع من وجوه:

public class MyObj
{
    public DateTime Date { get; set; }
    public string ConditionalValue1 { get; set; }
    public int ConditionalValue2 { get; set; }
    public int OtherValue { get; set; }

    //for test purposes only, i would like to avoid doing this
    public bool CompareFields(MyObj toBeCompared)
    {
        return ConditionalValue1 == toBeCompared.ConditionalValue1 &&
               ConditionalValue2 == toBeCompared.ConditionalValue2; 
    }
}

لدي قائمة من لهم ، المأهولة بالسكان على النحو التالي:

//list is ordered for semplicity, but it won't be by default
//list is a result of a group by too
var myList = new[]
{
    new MyObj { Date = new DateTime(2009, 10, 20), ConditionalValue1 = "A", ConditionalValue2 = 1, OtherValue = 1 },
    new MyObj { Date = new DateTime(2009, 10, 21), ConditionalValue1 = "A", ConditionalValue2 = 1, OtherValue = 2 },
    new MyObj { Date = new DateTime(2009, 10, 22), ConditionalValue1 = "B", ConditionalValue2 = 1, OtherValue = 3 },
    new MyObj { Date = new DateTime(2009, 10, 23), ConditionalValue1 = "A", ConditionalValue2 = 2, OtherValue = 4 },
    new MyObj { Date = new DateTime(2009, 10, 24), ConditionalValue1 = "A", ConditionalValue2 = 2, OtherValue = 5 },
    new MyObj { Date = new DateTime(2009, 10, 25), ConditionalValue1 = "A", ConditionalValue2 = 1, OtherValue = 6 },
    //Note the hole for day 26
    new MyObj { Date = new DateTime(2009, 10, 27), ConditionalValue1 = "A", ConditionalValue2 = 1, OtherValue = 7},
};

أراد (pseudocode):

List = 
  { ListOfObjects }, //First has date = "2009/10/20", last has = "2009/10/21" 
  { ListOfObjects }, //First has date = "2009/10/22", last has = "2009/10/22" //reason: doesn't match Value1
  { ListOfObjects }, //First has date = "2009/10/23", last has = "2009/10/24" 
  { ListOfObjects }, //First has date = "2009/10/25", last has = "2009/10/25" //reason: doesn't match Value2
  { ListOfObjects }  //First has date = "2009/10/27", last has = "2009/10/27" //reason: there is no "2009/10/26" object

الاختبارات حتى الآن:

//i pick the first element, to be compared with the next ones
var firstInList = myList.First();
//take while date is consequent and fields are compared
var partialList = myList
    .TakeWhile(
        (obj, index) => obj.Date == firstInList.Date.AddDays(index) &&
                        obj.CompareFields(firstInList)
    );

هذا هو جزئيا العامل ، كما وبطبيعة الحال فإنه سيعود النتائج الصحيحة فقط لأول مطابقة العناصر.

أنا يمكن أن Skip(count) قائمة حتى 0 العناصر ، ولكن أود أن استخدام group by, باستخدام IEqualityComparer بدلا من الأسلوب CompareFields.

هل كانت مفيدة؟

المحلول

كنت قد تكون قادرة على استخدام Enumerable.GroupBy.ولكن لدي شعور أنه قد يتكرر خلال مجموعة كاملة.إذا كان الأمر كذلك, يمكنك دائما إنشاء الخاصة بك SequencedGroupBy طريقة التمديد.

تحذير: لن تعمل بالتوازي مع ملحقات (AsParallel)

DateTime lastGroupDate = DateTime.MinValue;
DateTime lastDate = DateTime.MinValue;

IEnumerable<IGrouping<DateTime, MyObj>> groups = myList
    .GroupBy(o =>
        {
            if (lastGroupDate != DateTime.MinValue &&
                o.Date.AddDays(-1) == lastDate)
            {
                lastDate = o.Date;
            }
            else
            {
                lastGroupDate = o.Date;
                lastDate = o.Date;
            }

            return lastGroupDate;
        }
    );

foreach(IGrouping<DateTime, MyObj> grouping in groups)
{
    // grouping.Key == the grouped date / first in sequence

    foreach(MyObj obj in grouping)
    {
        // obj.Date == actual date
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top