string[] filesOfType1 = GetFileList1();
string[] filesOfType2 = GetFileList2();
var cookieMap = new Dictionary<string, CookieContainer>();
Action<string, Func<string, KeyValuePair<string, CookieContainer>>> addToMap = (filename, pairGetter) =>
{
KeyValuePair<string, CookieContainer> cookiePair;
try
{
cookiePair = pairGetter(filename);
}
catch
{
Console.WriteLine("An error was encountered while trying to read " + file + ".");
return;
}
if (cookieMap.ContainsKey(cookiePair.Key))
{
if (cookiePair.Value.Count > cookieMap[cookiePair.Key].Count)
{
cookieMap[cookiePair.Key] = cookiePair.Value;
}
}
else
{
cookieMap.Add(cookiePair.Key, cookiePair.Value);
}
};
foreach (string file in filesOfType1)
{
addToMap(file, GetType1FileCookiePair);
}
foreach (string file in filesOfType2)
{
addToMap(file, GetType2FileCookiePair);
}
必须保留的显着特征:
CookieContainer
具有更高Count
的{{1}}具有更高的优先级,即如果同一个键有两个(键,值)组合,并且都来自同一文件类型,我们选择一个更高value.Count
。我最好的尝试就像这样:
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);
但是它不够优雅并且填补了评论块看起来像个婊子。现在我很高兴保持程序性,但我认为看看人们是否能想出一些非常聪明的东西可能是一个有趣的挑战。
答案 0 :(得分:3)
这是我的尝试 - 将任务分成三个不同的陈述似乎最简单。
我正在使用一个辅助函数,如果该操作抛出异常,则返回null - 为了与Omer van Kloeten的答案保持一致,我称之为Swallow()
另外,我没有使用LINQ语法,只是System.Linq.Enumerable提供的扩展方法
最后,请注意,这是未编译的 - 因此请将其视为意图。
// 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);
答案 1 :(得分:2)
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;
} );
编辑:更新了Cookie检索,以满足“类型1的文件比类型2的文件更重要”的要求。
答案 2 :(得分:1)
请原谅我实际上并没有继续编译,但这就是我要去做的方式:
var cookieMap = (from pair in
(from f1 in filesOfType1
select Swallow(() => GetType1FileCookiePair(f1)))
.Concat(from f2 in filesOfType2
select Swallow(() => GetType2FileCookiePair(f2)))
.SelectMany(dict => dict)
group pair by pair.Key into g
select g)
.ToDictionary(g => g.Key, g => g.Select(pair => pair.Value)
.OrderByDescending(value => value.Count)
.First());
Swallow
如下:
private static T Swallow<T>(Func<T> getT)
{
try { return getT(); } catch { }
return default(T);
}
爱我一个好的LINQ。
Swallow
方法,可以吞下所有例外情况。Swallow
。现在按预期工作。