简体   繁体   English

将列表中的离散值分离到不同的列表对象C#中

[英]seperate distict values from a list into different list object c#

I have a list object where I have 100 numbers. 我有一个列表对象,其中有100个数字。 I want to separate all list object with respect to all unique numbers. 我想针对所有唯一数字分隔所有列表对象。

Here is my list object 这是我的清单对象

public class USERDETAILS
{
     private long _ID;
     public long ID
     {
         get { return _ID; }
         set { _ID = value; }
     }

     private long _MSISDN;
     public long MSISDN
     {
         get { return _MSISDN; }
         set { _MSISDN = value; }
     }
}

List<USERDETAILS> lstUSERDETAILS = new List<USERDETAILS>();

I have 10 numbers in my list 我的清单上有10个号码

ID  MSISDN
101 9000001
102 9000002
103 9000002
104 9000003
105 9000003
106 9000003
107 9000007
108 9000008
109 9000009
110 9000010

I want to get duplicated entries in different list objects. 我想在不同的列表对象中获得重复的条目。 Here's expected output: 这是预期的输出:

1st list object: 第一个列表对象:

ID  MSISDN
101 9000001
102 9000002
104 9000003
107 9000007
108 9000008
109 9000009
110 9000010

2nd list object: 第二个列表对象:

ID  MSISDN
103 9000002
105 9000003

3rd list object: 第三个清单物件:

ID  MSISDN
106 9000003

I have tried with linq group by ; 我曾尝试过linq group by;

var listOfUnique_USERDETAILS_Lists = listUSERDETAILS.GroupBy(p => p.MSISDN).Select(g => g.ToList());

Also I had tried iterating it over for loop to get distinct numbers and then putting up it in list<USERDETAILS> object and then creating it in new list of duplicated entries but want to do it with more simplified way. 我也尝试过遍历for循环以获取不同的数字,然后将其放在list<USERDETAILS>对象中,然后在新的重复条目列表中创建它,但希望以更简化的方式进行操作。

Here you go. 干得好。

If you run this: 如果运行此命令:

List<UserDetails> source = new List<UserDetails>();

UserDetails[][] grouping = source
                         .GroupBy( x=> x.MSISDN )
                         .Select( y => y.OrderBy( z => z.ID ).ToArray() )
                         .ToArray()
                         ;

gives you an array of UserDetails[] . 给你一个UserDetails[]数组。

grouping[n] gives you the array of all the UserDetails objects sharing the same MSISDN value, ordered by their ID property. grouping[n]为您提供共享相同MSISDN值的所有UserDetails对象的数组,按其ID属性排序。

grouping[n][0] will give you the first such object for that MSISDN . grouping[n][0]将为您提供该MSISDN的第一个此类对象。 Iterating over that will give you the "distinctified" set of "first" objects. 遍历该对象将为您提供“独特”的“第一个”对象集。 Since every grouping is guaranteeed to have at least one such item, we can simply say: 由于保证每个分组至少有一个这样的项目,我们可以简单地说:

UserDetails[] firstList = grouping.Select( x => x.First() ).ToArray() ;

You can get your 2nd, 3rd, 4th, etc. lists by: 您可以通过以下方式获取第二,第三,第四等列表:

        int n = 2 ; // specify a suitable value for n such that n > 0 (1:1st, 2:2nd, etc.)
        UserDetails[] nthList = grouping.Select( x => x.Skip(n-1).FirstOrDefault() ).Where( x => x != null ).ToArray() ;

Note: since the 2d array is jagged (and so, every MSISDN may not have an nth element, we use Skip(n-1).FirstOrDefault().Where( x => x != null ) to toss the missing items. 注意:由于2d数组是锯齿状的 (因此,每个MSISDN可能没有第n个元素,因此我们使用Skip(n-1).FirstOrDefault().Where( x => x != null )来丢掉丢失的项。

The more general solution would be to take the grouping[][] and *transpose its rows and columns, such that grouping[x][y] becomes ranking[y][x] . 更通用的解决方案是采用grouping[][]并*对其行和列进行转置,以使grouping[x][y]成为ranking[y][x] That lets you look at the transposed ranking[][] as having ranking[0] being the UserDetails[] that is your 1st-ranked objects across all MSISDN values, ranking[0] being your 2nd ranked objects across all MSISDN values, etc. 这样一来,您就可以将转置后的ranking[][]视为具有ranking[0]UserDetails[] ,它是您在所有MSISDN值中ranking[0]第一的对象, ranking[0]是您在所有MSISDN值中ranking[0]第二的对象, MSISDN

You you'll probably want to do something more than a simple transposition since any given MSISDN may not have an nth-ranked item, for any value of n larger than 0. 您可能需要做的事情不只是简单的转换,因为对于任何大于0的n值,任何给定的MSISDN可能都没有第n个项目。

I believe (untested) that you can do the 2-D transposition something like this with LINQ: 我相信(未经测试)您可以使用LINQ进行二维转置:

UserDetails[][] ranking = Enumerable
                          .Range( 0 ,grouping.Max(x => x.Length) )
                          .Select( rank => Enumerable
                                           .Range(0,grouping.Length)
                                           .Select( msisdn => grouping[msisdn].Skip(rank-1).FirstOrDefault() )
                                           .Where( x => x != null )
                                           .ToArray()
                          )
                          .ToArray()
                          ;

At the end of which ranking[0] should be your first list, ranking[1] your second list and ranking[2] your third list. 在该列表的末尾, ranking[0]应该是您的第一个列表, ranking[1]您的第二个列表, ranking[2]您的第三个列表。

So first group the items, using GroupBy , then you can iterate over the groups and project them out to IEnumerator objects, pulling out the groups that still have items left and yielding the next item, until none of the groups have any items. 因此,首先使用GroupBy对项目进行分组,然后可以遍历这些组并将它们投影到IEnumerator对象,拉出仍剩下项目的组并产生下一个项目,直到这些组中没有任何项目。

//TODO give better name
public static IEnumerable<IEnumerable<T>> Foo<T, TKey>(
    IEnumerable<T> source, Func<T, TKey> selector)
{
    var groups = source.GroupBy(selector)
        .Select(group => group.GetEnumerator())
        .ToList();
    while (groups.Any())
    {
        yield return groups.Select(iterator => iterator.Current);
        groups = groups.Where(iterator => iterator.MoveNext())
            .ToList();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM