首页 文章

从结果列表中获取唯一数据

提问于
浏览
0

我有这样的数据 .

原始数据:
1 - > A - > 1 - > 2011 - > 2009
2 - > A - > 1 - > 2011 - > 2010
3 - > B - > 1 - > 2008 - > 2008
4 - > B - > 1 - > 2009 - > 2009
5 - > A - > 2 - > 2008 - > 2009
6 - > B - > 1 - > 2008 - > 2011

第1步:按列2分区 .
1 - > A - > 1 - > 2011 - > 2009
2 - > A - > 1 - > 2011 - > 2010
5 - > A - > 2 - > 2008 - > 2009
3 - > B - > 1 - > 2008 - > 2008
4 - > B - > 1 - > 2009 - > 2009
6 - > B - > 1 - > 2008 - > 2011

步骤2:按列3(降序)应用排序,如果在第一个位置找到唯一记录则返回该结果,否则仅在模糊记录上应用下一个排序标准,即重复步骤#2 .
5 - > A - > 2 - > 2008 - > 2009 //Unique Record
1 - > A - > 1 - > 2011 - > 2009
2 - > A - > 1 - > 2011 - > 2010
3 - > B - > 1 - > 2008 - > 2008
4 - > B - > 1 - > 2009 - > 2009
6 - > B - > 1 - > 2008 - > 2011

所以现在我们的结果将是这样的 . 清单1:
5 - > A - > 2 - > 2008 - > 2009

清单2:由于我们已经能够在"A"中找到唯一记录,因此从剩余列表中删除其数据
3 - > B - > 1 - > 2008 - > 2008
4 - > B - > 1 - > 2009 - > 2009
6 - > B - > 1 - > 2008 - > 2011

步骤3:应用下一个排序标准,即column4(降序),但位置1的数据不明确
3 - > B - > 1 - > 2008 - > 2008
6 - > B - > 1 - > 2008 - > 2011
4 - > B - > 1 - > 2009 - > 2009

步骤4:仅对模糊结果应用下一个排序标准,即column5(降序)
6 - > B - > 1 - > 2008 - > 2011 //Unique record
3 - > B - > 1 - > 2008 - > 2008

所以最终列表将包含如下结果 .
5 - > A - > 2 - > 2008 - > 2009
6 - > B - > 1 - > 2008 - > 2011

所以我希望在应用每个排序标准后从结果中获取唯一数据 . 我不知道我能否以更好的方式解释我的问题,我知道通过使用for循环和比较数据我可以解决它但只需要帮助解决它最好的方法 .

3 回答

  • 0

    对我来说,最好的方法,就是涉及最少量循环的方法就是这样:

    第2列需要一个LINQ组(第1步:第2列分区)

    这将为您提供两个组的匿名列表,其中包含组[0]中A的所有元素和组[1]中B的元素 .

    因此,您需要循环遍历组数组,并在第3列应用排序之后获取第一个元素,然后按列4降序,然后按列5降序 . 此处的重要部分是ThenBy .

    所以它基本归结为:

    For each objGroup in dtb.Group(....)
    objGroup.OrderByDescending(Column3)
    .ThenByDescending(Column4)
    .ThenByDescending(Column5).
    

    如果您需要正确的语法,请告诉我 .

  • 0

    我创建了一个类似下面的类来表示您的数据

    public class TestClass
        {
            private int _col1;
            private char _col2;
            private int _col3;
            private int _col4;
            private int _col5;
    
            public TestClass(int c1, char c2, int c3, int c4, int c5)
            {
                _col1 = c1;
                _col2 = c2;
                _col3 = c3;
                _col4 = c4;
                _col5 = c5;
            }
    
            public int Col1
            {
                get { return _col1; }
                set { _col1 = value; }
            }
    
            public char Col2
            {
                get { return _col2; }
                set { _col2 = value; }
            }
    
            public int Col3
            {
                get { return _col3; }
                set { _col3 = value; }
            }
    
            public int Col4
            {
                get { return _col4; }
                set { _col4 = value; }
            }
    
            public int Col5
            {
                get { return _col5; }
                set { _col5 = value; }
            }
        }
    

    然后我写了这个程序,似乎在某个你正在寻找的东西

    List<TestClass> test = new List<TestClass>();
    
                test.Add(new TestClass(1, 'A', 1, 2011, 2009));
                test.Add(new TestClass(2, 'A', 1, 2011, 2010));
                test.Add(new TestClass(3, 'B', 1, 2008, 2008));
                test.Add(new TestClass(4, 'B', 1, 2009, 2009));
                test.Add(new TestClass(5, 'A', 2, 2008, 2009));
                test.Add(new TestClass(6, 'B', 1, 2008, 2011));
    
                var first_ordered = from t in test
                                    orderby t.Col2, t.Col3 descending, t.Col4 descending, t.Col5 descending
                                    group new { t.Col1, t.Col3, t.Col4, t.Col5 } by t.Col2 into p
                                    select new
                                    {
                                        Col1 = p.First().Col1,
                                        Col2 = p.Key,
                                        Col3 = p.First().Col3,
                                        Col4 = p.First().Col4,
                                        Col5 = p.First().Col5
                                    };
    
                foreach(var f in first_ordered) 
                {
                    Console.WriteLine($"{f.Col1}, {f.Col2}, {f.Col3}, {f.Col4}, {f.Col5}");
                }
    

    它适用于'A'分区,对于'B'没有,但是你的解释中有一些东西似乎不正确:当你在文本中描述第3步时,你要求第4列有序下降,但在数据中,你把它们命令为升序 . 所以,我按照你写的文字,如果你想升序,你只需要我的代码,删除orderby子句中的“降序”,自动Linq将命令提到的字段升序 . 我希望它有所帮助!

  • 0

    您可以使用linq:

    namespace ConsoleApp4
    {
        class SortOrder
        {
        public Func<DataRec, object> PropName { get; set; }
        public bool Ascending { get; set; }
        }
    
        public class DataRec
        {
            public int ID { get; set; }
            public string Name { get; set; }
            public int Order { get; set; }
            public int Year1 { get; set; }
            public int Year2 { get; set; }
        }
        class Program
        {
    
    
            static void Main(string[] args)
            {
               List<DataRec> myData = new List<DataRec>();
    
            myData.Add(new DataRec() { ID = 1, Name = "A", Order = 1, Year1 = 2011, Year2 = 2009 });
            myData.Add(new DataRec() { ID = 2, Name = "A", Order = 1, Year1 = 2011, Year2 = 2010 });
            myData.Add(new DataRec() { ID = 3, Name = "B", Order = 1, Year1 = 2008, Year2 = 2008 });
            myData.Add(new DataRec() { ID = 4, Name = "B", Order = 1, Year1 = 2009, Year2 = 2009 });
            myData.Add(new DataRec() { ID = 5, Name = "A", Order = 2, Year1 = 2008, Year2 = 2009 });
            myData.Add(new DataRec() { ID = 6, Name = "B", Order = 1, Year1 = 2008, Year2 = 2011 });
    
            //var orderedData = myData.GroupBy(x=>x.Name, (key, group) =>group.OrderByDescending(x => x.Order).ThenBy(x => x.Year1).ThenByDescending(x => x.Year2).First()).ToList();
            List<SortOrder> sorting = new List<SortOrder>();
            sorting.Add(new SortOrder() { PropName = x => x.Order, Ascending = false });
            sorting.Add(new SortOrder() { PropName = x => x.Year1, Ascending = true });
            sorting.Add(new SortOrder() { PropName = x => x.Year2, Ascending = false });
    
            var orderedData = myData.GroupBy(x=>x.Name);
    
            IOrderedEnumerable<DataRec> sorted;
            List<DataRec> result = new List<DataRec>();
    
            foreach (var oneGroup in orderedData)
            {
                sorted = null;
                foreach (SortOrder oneSort in sorting)
                {
                    if (sorted == null)
                    {
                        sorted = oneSort.Ascending ? oneGroup.OrderBy(oneSort.PropName) : oneGroup.OrderByDescending(oneSort.PropName);                      
                    }
                    else
                    {
                        sorted = oneSort.Ascending ? sorted.ThenBy(oneSort.PropName): sorted.ThenByDescending(oneSort.PropName);
                    }
                }
                result.Add(sorted.First());
            }
        }
    

    首先我组(你称之为partision),然后我根据你的需要,使它成为动态并得到第一个记录 .

相关问题