好的,所以我一开始没有正确理解这个问题,所以我的第一个答案有点偏离,这是我的第二次尝试,我决定不在 linq 中做所有事情,因为这会很快变得非常混乱,这是一个允许的版本任何类型的字符,并给出所有列的计数。
private class Example
{
public string xvalue { get; set; }
}
//this will give you matches per column for any amount of chars
public static Dictionary<char, int[]> GetCount(IEnumerable<Example> matchAgainst,params char[] matches)
{
//maybe there is an easier way to do this in linq I am not sure
List<string> flattenedColumns = new List<string>();
foreach ( var target in matchAgainst )
{
for ( int i = 0 ; i < target.xvalue.Length ; i++ )
{
if ( flattenedColumns.Count <= i )
{
flattenedColumns.Add ( string.Empty );
}
flattenedColumns [ i ] += target.xvalue [ i ];
}
}
//now compose based on the chars
return ( from c in matches
select new
{
CharTarget = c ,
Counts = ( from col in flattenedColumns
select col.Count ( ( ch ) => ch == c ) ).ToArray ( )
} ).ToDictionary ( rslt => rslt.CharTarget , rslt => rslt.Counts );
}
public static void Do ( )
{
string curr = "";
List<Example> exampleList = new List<Example> ( );
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
for ( int k = 0 ; k < 10 ; k++ )
{
curr= i+""+j+""+k;
exampleList.Add ( new Example { xvalue = curr } );
}
var matches = GetCount ( exampleList , '1' , '2' , '3' );
var var1Col1 = matches [ '1' ] [ 0 ];
var var2Col1 = matches [ '2' ] [ 0 ];
//...
}
注意:
我不确定这是否是展平列的最佳方法,但它似乎是最直接的。
这是一个更通用的版本,我假设列只是对象数组,为了展平列,我只使用聚合和一个私有定义的类,该类表示一个对象是否已转换为
private class Row
{
public object[] Columns {get;set;}
}
public static Dictionary<object, int[]> GetCountByIndex(IEnumerable<Row> matchAgainst, params object[] matches)
{
bool firstTime = true;
return
( from key in matches
let flatCols = ( from Row row in matchAgainst select row.Columns ).Aggregate ( ( a , b ) =>
{
var retlen = a.Length;
if ( b.Length > a.Length )
retlen = b.Length;
object [ ] retv = new object [ retlen ];
//use bool flag to determine first time objects are being aggregated
if (!firstTime)
{
//do every other join
for ( int i = 0 ; i < retlen ; i++ )
{
List<object> curr = null;
if ( i >= a.Length )
{
curr = new List<object> ( );
}
else
{
curr = a [ i ] as List<object>;
}
if ( i < b.Length )
{
curr.Add ( b [ i ] );
}
retv [ i ] = curr;
}
}
else
{
//intialization
for ( int i = 0 ; i < retlen ; i++ )
{
List<object> curr = new List<object>( );
if ( i < a.Length )
{
curr.Add ( a [ i ] );
}
if ( i < b.Length )
{
curr.Add ( b [ i ] );
}
retv [ i ] = curr;
}
firstTime = false;
}
return retv;
} )
select new
{
Key = key ,
Value = ( from object obj in flatCols
select ( ( List<object> ) obj ).Count ( c => key.Equals ( c ) ) ).ToArray ( )
} ).ToDictionary ( keySel => keySel.Key , valSel => valSel.Value );
}