挑战:优雅地LINQify此程序代码
但这是不雅观的,在评论栏中填充内容看起来像个婊子。现在,我很高兴保持程序性,但我认为,看看人们是否能想出真正聪明的东西可能是一个有趣的挑战。请原谅我没有真正着手编写这篇文章,但我会这样做:挑战:优雅地LINQify此程序代码,linq,linq-to-objects,Linq,Linq To Objects,但这是不雅观的,在评论栏中填充内容看起来像个婊子。现在,我很高兴保持程序性,但我认为,看看人们是否能想出真正聪明的东西可能是一个有趣的挑战。请原谅我没有真正着手编写这篇文章,但我会这样做: var cookieMap = (filesOfType1.Select(file => GetType1FileCookiePair(file)) .Concat(filesOfType2.Select(file => GetType2FileCookiePair
var cookieMap = (filesOfType1.Select(file => GetType1FileCookiePair(file))
.Concat(filesOfType2.Select(file => GetType2FileCookiePair(file))))
.GroupBy(pair => pair.Key)
.Select(/* some way of selecting per the above bullets */)
.ToDictionary(pair => pair.Key, pair => pair.Value);
以下是:
好好爱我,林克
编辑:添加了一个将吞咽所有异常的吞咽方法。
编辑2:编译、修改等。添加。现在一切正常。
请原谅,我没有真正着手编写,但我会这样做:
var cookieMap = (filesOfType1.Select(file => GetType1FileCookiePair(file))
.Concat(filesOfType2.Select(file => GetType2FileCookiePair(file))))
.GroupBy(pair => pair.Key)
.Select(/* some way of selecting per the above bullets */)
.ToDictionary(pair => pair.Key, pair => pair.Value);
以下是:
好好爱我,林克
编辑:添加了一个将吞咽所有异常的吞咽方法。
编辑2:编译、修改等。添加。现在一切正常。
编辑:更新cookie检索以满足类型1的文件比类型2的文件更重要
编辑:更新cookie检索以满足类型1的文件比类型2的文件更重要。以下是我的尝试-似乎最简单的方法是将任务分成三个不同的语句 我使用了一个helper函数,如果操作抛出异常,它将返回null——为了与Omer van Kloeten的答案保持一致,我将此函数称为Swallow 另外,我没有使用LINQ语法,只是使用System.LINQ.Enumerable提供的扩展方法 最后,请注意,这是未编译的,因此将其视为意图
using CookiePair = KeyValuePair<string, CookieContainer>;
using CookieDictionary = Dictionary<string, CookieContainer>;
Func<string[], Func<string, CookiePair>, IEnumerable<CookiePair>> getCookies =
( files, pairGetter ) =>
files.SelectMany( filename => {
try { return new[] { pairGetter( filename ) }; }
catch { Console.WriteLine( "..." ); return new CookiePair[0]; }
} );
var type1Cookies = getCookies( filesOfType1, GetType1FileCookiePair ).ToArray( );
var type1CookieNames = type1Cookies.Select( p => p.Key ).ToArray( );
var type2Cookies = getCookies( filesOfType2, GetType2FileCookiePair )
.Where( p => !type1CookieNames.Contains( p.Key ) );
var cookieMap = type1Cookies.Concat( type2Cookies )
.Aggregate( new CookieDictionary( ), ( d, p ) => {
if( !d.ContainsKey( p.Key ) || p.Value.Count > d[p.Key].Count )
d[p.Key] = p.Value;
return d;
} );
这是我的尝试——将任务分成三个不同的语句似乎是最简单的 我使用了一个helper函数,如果操作抛出异常,它将返回null——为了与Omer van Kloeten的答案保持一致,我将此函数称为Swallow 另外,我没有使用LINQ语法,只是使用System.LINQ.Enumerable提供的扩展方法 最后,请注意,这是未编译的,因此将其视为意图
using CookiePair = KeyValuePair<string, CookieContainer>;
using CookieDictionary = Dictionary<string, CookieContainer>;
Func<string[], Func<string, CookiePair>, IEnumerable<CookiePair>> getCookies =
( files, pairGetter ) =>
files.SelectMany( filename => {
try { return new[] { pairGetter( filename ) }; }
catch { Console.WriteLine( "..." ); return new CookiePair[0]; }
} );
var type1Cookies = getCookies( filesOfType1, GetType1FileCookiePair ).ToArray( );
var type1CookieNames = type1Cookies.Select( p => p.Key ).ToArray( );
var type2Cookies = getCookies( filesOfType2, GetType2FileCookiePair )
.Where( p => !type1CookieNames.Contains( p.Key ) );
var cookieMap = type1Cookies.Concat( type2Cookies )
.Aggregate( new CookieDictionary( ), ( d, p ) => {
if( !d.ContainsKey( p.Key ) || p.Value.Count > d[p.Key].Count )
d[p.Key] = p.Value;
return d;
} );
此外,我认为Max将返回一个double.Edited re异常。IIRC,Max有一个通用重载。而且我认为Max会返回一个双重的。编辑过的re异常。IIRC,Max有一个泛型重载。从我所看到的,您显示的原始代码不满足类型1的文件比类型2约束的文件更重要-如果类型2文件的计数更高,代码将覆盖类型1 cookie容器。哦,很好的捕获,谢谢Bevan!从我所看到的,您显示的原始代码不满足类型1的文件比类型2约束的文件更重要-如果类型2文件具有更高的计数,代码将覆盖类型1 cookie容器。噢,很好的捕获,谢谢Bevan!其中pair=>!pairsOfType1.Containsp=>p.Key==pair.Key;是不正确的,因为它会在不检查的情况下过滤掉type2中计数较高的对。请检查原始问题-类型1的Domenic编写的文件比类型2的文件更重要,因此Where子句是正确的,尽管原始代码不满足此要求。为什么需要在何处调用类型2?一个&&条件还不够吗?@Hosam-是的,我可以使用&&而不是两个Where调用,将产生相同的效果;我更喜欢一系列简单的测试,而不是一个更复杂的测试。这是一个聪明的小精灵,尤其是第三部分+1.其中pair=>!pairsOfType1.Containsp=>p.Key==pair.Key;是不正确的,因为它会在不检查的情况下过滤掉type2中计数较高的对。请检查原始问题-类型1的Domenic编写的文件比类型2的文件更重要,因此Where子句是正确的,尽管原始代码不满足此要求。为什么需要在何处调用类型2?一个&&条件还不够吗?@Hosam-是的,我可以使用&&而不是两个Where调用,将产生相同的效果;我更喜欢一系列简单的测试,而不是一个更复杂的测试。这是一个聪明的小精灵,尤其是第三部分+1.
using CookiePair = KeyValuePair<string, CookieContainer>;
using CookieDictionary = Dictionary<string, CookieContainer>;
Func<string[], Func<string, CookiePair>, IEnumerable<CookiePair>> getCookies =
( files, pairGetter ) =>
files.SelectMany( filename => {
try { return new[] { pairGetter( filename ) }; }
catch { Console.WriteLine( "..." ); return new CookiePair[0]; }
} );
var type1Cookies = getCookies( filesOfType1, GetType1FileCookiePair ).ToArray( );
var type1CookieNames = type1Cookies.Select( p => p.Key ).ToArray( );
var type2Cookies = getCookies( filesOfType2, GetType2FileCookiePair )
.Where( p => !type1CookieNames.Contains( p.Key ) );
var cookieMap = type1Cookies.Concat( type2Cookies )
.Aggregate( new CookieDictionary( ), ( d, p ) => {
if( !d.ContainsKey( p.Key ) || p.Value.Count > d[p.Key].Count )
d[p.Key] = p.Value;
return d;
} );
// Handle all files of type 1
var pairsOfType1 =
filesOfType1
.Select( file => Swallow( pairGetter(file)))
.Where( pair => pair != null);
// Handle files of type 2 and filter out those with keys already provided by type 1
var pairsOfType2 =
filesOfType2
.Select( file => Swallow( pairGetter(file)))
.Where( pair => pair != null);
.Where( pair => !pairsOfType1.Contains(p => p.Key == pair.Key));
// Merge the two sets, keeping only the pairs with the highest count
var cookies =
pairsOfType1
.Union( pairsOfType2)
.GroupBy( pair => pair.Key)
.Select( group => group.OrderBy( pair => pair.Value.Count).Last());
.ToDictionary( pair => pair.Key);