我有一个列表对象,其中有100个数字。我想根据所有唯一的数字来分隔所有列表对象
这是我的列表对象
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>();
我的列表中有10个数字
ID MSISDN
101 9000001
102 9000002
103 9000002
104 9000003
105 9000003
106 9000003
107 9000007
108 9000008
109 9000009
110 9000010
我想在不同的列表对象中得到重复的条目。以下是预期输出:
第一个列表对象:
ID MSISDN
101 9000001
102 9000002
104 9000003
107 9000007
108 9000008
109 9000009
110 9000010
第二个列表对象:
ID MSISDN
103 9000002
105 9000003
第三个列表对象:
ID MSISDN
106 9000003
我已经尝试了linq group by;
var listOfUnique_USERDETAILS_Lists = listUSERDETAILS.GroupBy(p => p.MSISDN).Select(g => g.ToList());
我也试过迭代它在for循环中获得不同的数字,然后把它放在list<USERDETAILS>
对象中,然后在新的重复条目列表中创建它,但想用更简化的方式来做。
给你
如果你运行这个:
List<UserDetails> source = new List<UserDetails>();
UserDetails[][] grouping = source
.GroupBy( x=> x.MSISDN )
.Select( y => y.OrderBy( z => z.ID ).ToArray() )
.ToArray()
;
给出一个UserDetails[]
数组。
grouping[n]
给出了共享相同MSISDN
值的所有UserDetails
对象的数组,按它们的ID
属性排序。
grouping[n][0]
将为MSISDN
提供第一个这样的对象。迭代它将得到"第一"对象的"明确"集合。由于每个组都保证至少有一个这样的项,我们可以简单地说:
UserDetails[] firstList = grouping.Select( x => x.First() ).ToArray() ;
你可以得到你的第二,第三,第四等列表:
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() ;
注意:由于2d数组是锯齿状的(因此,每个MSISDN
都可能没有第n个元素,我们使用Skip(n-1).FirstOrDefault().Where( x => x != null )
来丢弃缺失的元素。
更一般的解决方案是将grouping[][]
和*转置它的行和列,这样grouping[x][y]
变成ranking[y][x]
。这样,你就可以把转置后的ranking[][]
看作ranking[0]
是UserDetails[]
,它是所有MSISDN
值中排名第一的对象,ranking[0]
是所有MSISDN
值中排名第二的对象,等等。
对于n大于0的任何值,您可能想要做的不仅仅是简单的换位,因为任何给定的MSISDN
都可能没有排名第n的项。
我相信(未经测试)你可以用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()
;
在结尾ranking[0]
应该是你的第一个列表,ranking[1]
是你的第二个列表,ranking[2]
是你的第三个列表。
因此,首先使用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();
}
}