本文整理汇总了C#中Dictionary.GroupBy方法的典型用法代码示例。如果您正苦于以下问题:C# Dictionary.GroupBy方法的具体用法?C# Dictionary.GroupBy怎么用?C# Dictionary.GroupBy使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Dictionary
的用法示例。
在下文中一共展示了Dictionary.GroupBy方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: EBIDatasetParser
public EBIDatasetParser()
{
var keymap = new Dictionary<string, ColumnName>();
keymap["Array Data File"] = ColumnName.Sample;
//E-MTAB-365
keymap["Characteristics[Age]"] = ColumnName.Age;
keymap["Characteristics[Grade::Scarff Bloom Richardson]"] = ColumnName.Grade;
keymap["Characteristics[ESR1::Protein expression]"] = ColumnName.ER;
keymap["Characteristics[PGR::Protein expression]"] = ColumnName.PR;
keymap["Characteristics[ERBB2::Protein expression]"] = ColumnName.HER2;
//E-TABM-158
keymap["Characteristics [EstrogenReceptorStatus]"] = ColumnName.ER;
keymap["Characteristics [Progesterone Receptor status]"] = ColumnName.PR;
keymap["Characteristics [ErbB2 positive (IHC)]"] = ColumnName.HER2;
keymap["Characteristics [dead of disease]"] = ColumnName.DeadOfDisease;
keymap["Characteristics [node positive]"] = ColumnName.NodalStatus;
keymap["Characteristics [TumorStaging]"] = ColumnName.TumorStage;
keymap["Characteristics [alive at endpoint]"] = ColumnName.OverallServive;
keymap["Characteristics [TumorGrading]"] = ColumnName.Grade;
nameKeyMap = keymap.GroupBy(m => m.Value).ToDictionary(m => m.Key, m => new HashSet<string>(from n in m select n.Key));
}
示例2: AggregateResult
public AggregateResult(IEnumerable<GameResult> results)
{
_playerToScoreMap = new Dictionary<BotPlayer, int>();
results.SelectMany(x => x.Players).Each(x => _playerToScoreMap[x] = 0);
results.Each(result =>
{
if (result.IsTie)
{
result.Players.Each(player =>
{
_playerToScoreMap[player]++;
});
}
else
{
_playerToScoreMap[result.Winner] += 3;
}
});
var winners = _playerToScoreMap.GroupBy(x => x.Value).OrderByDescending(x => x.Key).First();
if (winners.Count() == _playerToScoreMap.Count)
{
IsTie = true;
}
else
{
Winner = winners.First().Key;
}
}
示例3: Merge
/// <summary>
/// if needed, will merge the images base on page in the image names
/// </summary>
/// <param name="imageBytes"></param>
/// <param name="imageNames"></param>
/// <returns></returns>
public Dictionary<PageImageIndex, System.Drawing.Image> Merge(Dictionary<PageImageIndex, System.Drawing.Image> imagesList, string outputPath)
{
var imageListByPage = imagesList.GroupBy(i => i.Key.PageIndex);
var newImageList = new Dictionary<PageImageIndex, System.Drawing.Image>();
foreach (var imagesInfo in imageListByPage)
{
var imagesPage = new Dictionary<PageImageIndex, System.Drawing.Image>();
foreach (var item in imagesInfo)
{
var image = item.Value;
if (item.Value == null)
{
var imagePath = string.Format(@"{0}\{1}", outputPath, item.Key.ImageName);
image = new System.Drawing.Bitmap(imagePath);
}
imagesPage.Add(item.Key, image);
}
//var imagesPage = imagesInfo.Select(i => i).ToDictionary(x => x.Key, x => x.Value);
var keyValue = MergeGroup(imagesPage, outputPath);
newImageList.Add(keyValue.Key, keyValue.Value);
}
return newImageList;
}
示例4: InitCaches
public void InitCaches()
{
var db = new FacesDBDataContext(_connectionString);
_faceUKeyLookup = db.Faces.ToDictionary(x => x.FaceUKey, x => (api.Face) new FaceImpl(x, _m, null));
var query = (from f in db.Faces join p in db.Persons on f.PersonID equals p.PersonID select new { f, p });
_Faces = new Dictionary<api.Face,api.Person>();
Dictionary<int, api.Person> persons = new Dictionary<int,api.Person>();
foreach (var x in query) {
// todo; build pers dic at same time...
api.Person person = null;
if (!persons.TryGetValue(x.p.PersonID, out person))
{
person = (api.Person)new PersonImpl(x.p.FirstName, x.p.LastName, x.p.PersonID);
persons.Add(person.Id, person);
}
api.Face thisFace = _faceUKeyLookup[x.f.FaceUKey];
thisFace.Person = person;
_Faces.Add(thisFace, person);
}
_Persons = _Faces.GroupBy(x => x.Value).ToDictionary(x => x.Key, x => x.Select(y=>y.Key).ToList());
_allPersonsLookup = persons;
foreach (var pers in db.Persons) // add in other persons that don't have faces.
{
if (!_allPersonsLookup.ContainsKey(pers.PersonID))
_allPersonsLookup.Add(pers.PersonID, (api.Person)new PersonImpl(pers.FirstName, pers.LastName, pers.PersonID));
}
_PicturesToFaces = db.Faces
.ToLookup(x => x.PictureID, x => _faceUKeyLookup[x.FaceUKey]);
}
示例5: GenerateReport
public Contracts.ExpensesReportDto GenerateReport()
{
// from user Id to user Id
var expenseMap = new Dictionary<Tuple<int, int>, decimal>();
Action<int, int, decimal> addToMap = (fromUser, toUser, amount) =>
{
var key = new Tuple<int, int>(fromUser, toUser);
if (expenseMap.ContainsKey(key))
amount += expenseMap[key];
if (amount != 0)
expenseMap[key] = amount;
else
expenseMap.Remove(key);
};
// add expenses
var allExpenses = DataContext.ExpenseItemsAsLightDto.ToArray();
var calculator = new CostCalculatorStrategy();
foreach (var expense in DataContext.Expenses.Where(e => e.Pricing != null).ToArray())
{
var expenseItems = allExpenses.Where(ei => ei.ExpenseId == expense.Id);
foreach (var costData in calculator.CalculateCosts(expense, expenseItems))
{
addToMap(costData.UserId, expense.Creator.Id, costData.Cost);
}
}
// remove bi-directional items
NormalizeMap(expenseMap);
// build result
var resultItems = new List<ExpensesUserReportDto>();
var allUsers = DataContext.UsersAsLightDto.ToDictionary(u=>u.Id);
foreach (var emi in expenseMap.GroupBy(em => em.Key.Item1))
{
var user = allUsers[emi.Key];
resultItems.Add(new ExpensesUserReportDto()
{
UserId = user.Id,
FullName = user.FullName,
TotalCost = emi.Sum(ei => ei.Value),
CostDetails = emi.Select(ei =>
new ExpensesCostDetailDto() {
Cost = ei.Value,
UserId = ei.Key.Item2,
FullName = allUsers[ei.Key.Item2].FullName
}).ToArray()
});
}
var result = new ExpensesReportDto();
result.Users = resultItems.ToArray();
return result;
}
示例6: GenerateSalesReportXMLMontly
public static void GenerateSalesReportXMLMontly(List<XMLReportInfo> salesReports)
{
var doc = new XDocument();
var sales = new XElement("sales");
foreach (var report in salesReports)
{
var sale = new XElement("sale", new XAttribute("vendor", report.Key));
var dates = report.Dates.Distinct().ToList();
Dictionary<DateTime, decimal> pair = new Dictionary<DateTime, decimal>();
for (int i = 0; i < dates.Count; i++)
{
pair[dates[i]] = 0;
}
for (int i = 0; i < report.Dates.Count; i++)
{
for (int j = 0; j < dates.Count; j++)
{
if (report.Dates[i] == dates[j])
{
pair[dates[j]] += report.Sums[i];
}
}
}
var monthExpens = pair.GroupBy(x => x.Key.Month).ToList();
for (int i = 0; i < monthExpens.Count(); i++)
{
var expense = new XElement("expenses", new XAttribute("month", CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(monthExpens[i].Key).Substring(0,3) + "-2013"));
decimal sum = 0;
foreach (var item in monthExpens)
{
foreach (var dailySum in item)
{
sum += dailySum.Value;
}
}
expense.Value = sum.ToString();
sale.Add(expense);
}
sales.Add(sale);
}
doc.Add(sales);
// Console.WriteLine(doc);
doc.Save(@"..\..\SalesReportByMonth.xml");
}
示例7: ValidateAndImportDocuments
/// <summary>
/// Parse and Import to DTOs
/// </summary>
/// <param name="spreadsheet"></param>
/// <param name="parseErrors"></param>
/// <returns></returns>
public List<DocumentImportDTO> ValidateAndImportDocuments(ExcelPackage spreadsheet, ref Dictionary<string, List<string>> parseErrors)
{
var items = new List<DocumentImportDTO>();
if (spreadsheet != null && spreadsheet.Workbook != null)
{
var worksheet = spreadsheet.Workbook.Worksheets.SingleOrDefault(x => x.Name == "Items");
if (worksheet == null)
{
return items;
}
var totalRows = worksheet.Dimension.End.Row;
for (var rowId = 2; rowId <= totalRows; rowId++)
{
//Prepare handle name for storing and grouping errors
var urlSegment = worksheet.GetValue<string>(rowId, 1);
var name = worksheet.GetValue<string>(rowId, 4);
var handle = urlSegment.HasValue() ? urlSegment : name;
if (string.IsNullOrWhiteSpace(handle) || items.Any(x => x.UrlSegment == urlSegment))
continue;
List<string> errors = parseErrors.ContainsKey(handle)
? parseErrors[handle]
: new List<string>();
var item = GetDocumentImportDataTransferObject(worksheet, rowId, name, ref errors);
parseErrors[handle] = errors;
items.Add(item);
}
//Remove duplicate errors
parseErrors = parseErrors.GroupBy(x => x.Value)
.Select(x => x.First())
.ToDictionary(pair => pair.Key, pair => pair.Value);
}
//Remove handles with no errors
parseErrors = parseErrors.Where(x => x.Value.Any()).ToDictionary(pair => pair.Key, pair => pair.Value);
return items;
}
示例8: ThreadNamesTest
public void ThreadNamesTest()
{
var rnd = new Random();
var range = Enumerable.Range(0, 50);
var rangeBack = new Dictionary<int, int>();
var rangeBackLocker = new object();
range.AsParallel().AsOrdered()
.WithDegreeOfParallelism(4).ForAll(x =>
{
lock (rangeBackLocker)
{
rangeBack.Add(x, Thread.CurrentThread.ManagedThreadId);
}
Thread.Sleep(100 * rnd.Next(10));
});
Assert.AreEqual(rangeBack.GroupBy(x=>x.Value).Count(), 4);
}
示例9: DictionaryExample
public void DictionaryExample()
{
// Mime Types
Dictionary<string, string> lookupTable = new Dictionary<string, string>();
lookupTable.Add("html", "text/html");
lookupTable.Add("htm", "text/html");
lookupTable.Add("png", "image/png");
lookupTable.Add("pdf", "application/pdf");
// Are there any type with more than one extension associated?
var t = lookupTable.GroupBy(x => x.Key).Select(x => new { MimeType = x.Key, Count = x.Count() }).Where(x => x.Count > 1);
// for each of the types with more than one extension...
foreach (var item in t)
{
// get the extensions:
var extensionArray = lookupTable.Where(x => x.Value == item.MimeType).Select(x => x.Key).ToArray<string>();
var extensions = string.Join(",", extensionArray);
Console.WriteLine("{0} has the following extensions: {1}", item, extensions);
}
}
示例10: WriteETWActor
private void WriteETWActor(StringBuilder sb, XElement provider, Dictionary<Tuple<int, int, string>, XElement> events)
{
sb.AppendFormat("public autostart actor actor_{0}", provider.Attribute("guid").Value.Replace("-", "").TrimStart('{').TrimEnd('}'));
sb.AppendLine();
sb.AppendLine("\t(EtwEvent.Node node)");
sb.AppendLine("{");
sb.AppendLine("\tprocess node accepts m:EtwProviderMsgEx");
sb.AppendFormat("\t\twhere (m.EventRecord.Header.ProviderId == {0} )", provider.Attribute("guid").Value);
sb.AppendLine();
sb.AppendLine("\t{");
sb.AppendLine("\t\tswitch(m.EventRecord.Header.Descriptor.Version)");
sb.AppendLine("\t\t{");
foreach (var etwEventGroup in events.GroupBy(p => p.Key.Item2))
{
sb.AppendFormat("\t\t\t//EventVersion {0}", etwEventGroup.Key);
sb.AppendLine();
sb.AppendFormat("\t\t\tcase $ {0} =>", etwEventGroup.Key);
sb.AppendLine();
sb.AppendLine("\t\t\t\tswitch(m.EventRecord.Header.Descriptor.Id)");
sb.AppendLine("\t\t\t\t{");
foreach (var etwEvent in etwEventGroup)
{
sb.AppendFormat("\t\t\t\t\t//{0} =>", GetEventName(etwEvent.Key.Item3, etwEvent.Key.Item2));
sb.AppendLine();
sb.AppendFormat("\t\t\t\t\tcase $ {0} =>", etwEvent.Key.Item1);
sb.AppendLine();
sb.AppendLine("\t\t\t\t\t\tswitch(m.Payload)");
sb.AppendLine("\t\t\t\t\t\t{");
sb.AppendFormat("\t\t\t\t\t\t\tcase decodedMsg: {0} from BinaryDecoder <{0}> =>", GetEventName(etwEvent.Key.Item3, etwEvent.Key.Item2));
sb.AppendLine();
sb.AppendLine("\t\t\t\t\t\t\t{");
sb.AppendLine("\t\t\t\t\t\t\t\tdecodedMsg.EtwKeywords = Keywords.Decode(m.EventRecord.Header.Descriptor.Keywords);");
sb.AppendLine("\t\t\t\t\t\t\t\tdecodedMsg.EventId = m.EventRecord.Header.Descriptor.Id;");
sb.AppendLine("\t\t\t\t\t\t\t\tdecodedMsg.ActivityId = m.EventRecord.Header.ActivityId;");
sb.AppendLine();
if (string.Equals(etwEvent.Value?.Attribute("opcode")?.Value, "win:Start"))
{
sb.AppendLine("\t\t\t\t\t\t\t\tint count = m.ExtendedData.Count;");
sb.AppendLine("\t\t\t\t\t\t\t\tif (count > 0)");
sb.AppendLine("\t\t\t\t\t\t\t\t{");
sb.AppendLine("\t\t\t\t\t\t\t\t\tarray <EventHeaderExtendedDataItem> items = m.ExtendedData;");
sb.AppendLine("\t\t\t\t\t\t\t\t\tEVENT_HEADER_EXT_TYPE_RELATED_ACTIVITYID dataItem = items[0].DataItem as EVENT_HEADER_EXT_TYPE_RELATED_ACTIVITYID;");
sb.AppendLine();
sb.AppendLine("\t\t\t\t\t\t\t\t\tif (dataItem != null)");
sb.AppendLine("\t\t\t\t\t\t\t\t\t\tdecodedMsg.RelatedActivityId = dataItem.RelatedActivityId;");
sb.AppendLine();
sb.AppendLine("\t\t\t\t\t\t\t\t\tdecodedMsg.ActivityTree = Facton_ActivityTree_Utils.GetActivityTree(decodedMsg.ActivityId, decodedMsg.RelatedActivityId, m.EventRecord.Header.ProcessId, m.EventRecord.Header.ThreadId);");
sb.AppendLine("\t\t\t\t\t\t\t\t}");
sb.AppendLine();
}
else
{
if (etwEvent.Key.Item1 != 0 && etwEvent.Key.Item1 != 65534)
{
sb.AppendLine("\t\t\t\t\t\t\t\tdecodedMsg.ActivityTree = Facton_ActivityTree_Utils.GetActivityTree(decodedMsg.ActivityId, m.EventRecord.Header.ProcessId, m.EventRecord.Header.ThreadId);");
}
}
sb.AppendFormat("\t\t\t\t\t\t\t\tep_{0} ep = endpoint ep_{0};", provider.Attribute("name").Value.Replace('-', '_'));
sb.AppendLine();
sb.AppendLine("\t\t\t\t\t\t\t\tdispatch ep accepts decodedMsg;");
sb.AppendLine("\t\t\t\t\t\t\t}");
sb.AppendLine("\t\t\t\t\t\t\tdefault =>");
sb.AppendFormat("\t\t\t\t\t\t\t\tThrowDecodingException(\"{0}\", \"{1}\");", provider.Attribute("name").Value, GetEventName(etwEvent.Key.Item3, etwEvent.Key.Item2));
sb.AppendLine();
sb.AppendLine("\t\t\t\t\t\t}");
sb.AppendLine();
}
sb.AppendLine("\t\t\t\t}");
sb.AppendLine();
}
sb.AppendLine("\t\t}");
sb.AppendLine("\t}");
sb.AppendLine("}");
sb.AppendLine();
}
示例11: BuildCachedVersionsList
void BuildCachedVersionsList(List<FileRevision> versions)
{
using (var sw = File.CreateText(DataFileName))
{
foreach (var fileGroup in versions.GroupBy(v => v.FileSpec))
{
// get in ascending order
var fileVersions = fileGroup.OrderBy(f => f.VssVersion).ToList();
var brokenVersions = new List<int>();
var notRetainedVersions = new List<int>();
var otherErrors = new Dictionary<int, string>();
if (IsShouldBePinned(fileGroup.Key))
{
// reduce file versions to latest only
fileVersions = fileVersions.Skip(fileVersions.Count - 1).ToList();
}
foreach (var file in fileVersions)
{
var inf = _cache.GetFileInfo(file.FileSpec, file.VssVersion);
if (inf == null)
throw new ApplicationException(string.Format("No in cache, but should be: {0}@{1}", file.FileSpec, file.VssVersion));
if (inf.ContentPath != null)
{
if (brokenVersions.Count > 0 || notRetainedVersions.Count > 0 || otherErrors.Count > 0)
{
var commentPlus = string.Format("\nBalme for '{0}' can be incorrect, because:", file.FileSpec);
if (brokenVersions.Count > 0)
{
commentPlus += "\n\tbroken vss versions: " +
string.Join(", ", brokenVersions.Select(v => v.ToString(CultureInfo.InvariantCulture)).ToArray());
}
if (notRetainedVersions.Count > 0)
{
commentPlus += "\n\tnot retained versions: " +
string.Join(", ", notRetainedVersions.Select(v => v.ToString(CultureInfo.InvariantCulture)).ToArray());
}
if (otherErrors.Count > 0)
{
foreach (var otherErrorsGroup in otherErrors.GroupBy(kvp => kvp.Value))
{
var revs = otherErrorsGroup.Select(kvp => kvp.Key.ToString(CultureInfo.InvariantCulture)).ToArray();
commentPlus += string.Format("\n\tError in VSS versions {0}: '{1}'", string.Join(", ", revs),
otherErrorsGroup.Key);
}
}
file.Comment += commentPlus;
}
sw.WriteLine("Ver:{0} Spec:{1} Phys:{2} User:{3} At:{4} DT:{5} Comment:{6}",
file.VssVersion,
file.FileSpec,
file.Physical,
file.User,
file.At.Ticks,
file.At,
file.Comment.Replace('\n', '\u0001')
);
notRetainedVersions.Clear();
brokenVersions.Clear();
otherErrors.Clear();
}
else if (inf.Notes == "not-retained")
notRetainedVersions.Add(file.VssVersion);
else if (inf.Notes == "broken-revision")
brokenVersions.Add(file.VssVersion);
else if (!string.IsNullOrWhiteSpace(inf.Notes))
otherErrors[file.VssVersion] = inf.Notes;
}
if (brokenVersions.Count > 0 || notRetainedVersions.Count > 0 || otherErrors.Count > 0)
throw new ApplicationException(string.Format("Absent content for latest file version: {0}", fileGroup.Key));
}
}
}
示例12: TypeMapper
static TypeMapper()
{
typeMapping = new Dictionary<string, Type>();
typeMapping.Add("bigint", typeof(long));
typeMapping.Add("int", typeof(int));
typeMapping.Add("smallint", typeof(short));
typeMapping.Add("tinyint", typeof(byte));
typeMapping.Add("decimal", typeof(decimal));
typeMapping.Add("numeric", typeof(decimal));
typeMapping.Add("money", typeof(decimal));
typeMapping.Add("smallmoney", typeof(decimal));
typeMapping.Add("bit", typeof(bool));
typeMapping.Add("float", typeof(float));
typeMapping.Add("real", typeof(double));
typeMapping.Add("datetime2", typeof(DateTime));
typeMapping.Add("datetime", typeof(DateTime));
typeMapping.Add("smalldatetime", typeof(DateTime));
typeMapping.Add("date", typeof(DateTime));
typeMapping.Add("datetimeoffset", typeof(DateTime));
typeMapping.Add("time", typeof(DateTime));
typeMapping.Add("timestamp", typeof(DateTime));
typeMapping.Add("nvarchar", typeof(string));
typeMapping.Add("char", typeof(string));
typeMapping.Add("varchar", typeof(string));
typeMapping.Add("text", typeof(string));
typeMapping.Add("nchar", typeof(string));
typeMapping.Add("ntext", typeof(string));
typeMapping.Add("varbinary", typeof(byte[]));
typeMapping.Add("binary", typeof(byte[]));
typeMapping.Add("image", typeof(byte[]));
typeMapping.Add("uniqueidentifier", typeof(Guid));
reverseTypeMapping = typeMapping
.GroupBy(kv => kv.Value, kv => kv.Key)
.ToDictionary(g => g.Key, g => g.First());
reverseTypeMapping.Add(typeof(char[]), "nchar");
reverseTypeMapping.Add(typeof(int?), "int");
reverseTypeMapping.Add(typeof(uint), "int");
reverseTypeMapping.Add(typeof(uint?), "int");
reverseTypeMapping.Add(typeof(long?), "bigint");
reverseTypeMapping.Add(typeof(ulong), "bigint");
reverseTypeMapping.Add(typeof(ulong?), "bigint");
reverseTypeMapping.Add(typeof(short?), "smallint");
reverseTypeMapping.Add(typeof(ushort), "smallint");
reverseTypeMapping.Add(typeof(ushort?), "smallint");
reverseTypeMapping.Add(typeof(byte?), "tinyint");
reverseTypeMapping.Add(typeof(sbyte), "tinyint");
reverseTypeMapping.Add(typeof(sbyte?), "tinyint");
reverseTypeMapping.Add(typeof(char), "tinyint");
reverseTypeMapping.Add(typeof(char?), "tinyint");
reverseTypeMapping.Add(typeof(decimal?), "decimal");
reverseTypeMapping.Add(typeof(bool?), "bit");
reverseTypeMapping.Add(typeof(float?), "float");
reverseTypeMapping.Add(typeof(double?), "real");
reverseTypeMapping.Add(typeof(DateTime?), "datetime2");
reverseTypeMapping.Add(typeof(Guid?), "uniqueidentifier");
}
示例13: OverrideWithInputs
IEnumerable<IGrouping<string, string>> OverrideWithInputs(IEnumerable<IGrouping<string,string>> parameters)
{
var overrides = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
if (Configuration != null)
overrides.Add("Configuration", Configuration);
if (Incremental)
overrides.Add("Incremental", "True");
return overrides.GroupBy(x => x.Key, x => x.Value).Concat(parameters.Where(param => !overrides.ContainsKey(param.Key)));
}
示例14: AverageHitsPerSecondPerHourSectionOutput
private void AverageHitsPerSecondPerHourSectionOutput(Dictionary<DateTime, int> hitsPerSecond)
{
Console.WriteLine();
OutputHeading("Average hits per second, by hour");
var groupedHourlyList = hitsPerSecond.GroupBy(u => u.Key.Hour)
.Select(grp => new { GroupID = grp.Key, subList = grp.ToList() })
.ToList();
foreach (var hourlyHits in groupedHourlyList)
{
Console.WriteLine("{0,2:D2}-{1,2:D2} : {2:0}", hourlyHits.GroupID, hourlyHits.GroupID + 1, hourlyHits.subList.Average(c => c.Value));
}
}
示例15: ResolveTagNamesFromPath
private DfmTagNameResolveResult ResolveTagNamesFromPath(string fencesPath, string[] fencesCodeLines, string tagName, Regex regexToExtractCode)
{
var lazyResolveResults =
_dfmTagNameLineRangeCache.GetOrAdd(fencesPath,
path => new Lazy<ConcurrentDictionary<string, DfmTagNameResolveResult>>(
() =>
{
var linesOfSnippetComment = new Dictionary<long, string>();
for (long i = 0; i < fencesCodeLines.Length; i++)
{
var match = regexToExtractCode.Match(fencesCodeLines[i]);
if (match.Success)
{
linesOfSnippetComment.Add(i + 1, match.Groups[1].Value);
}
}
var excludedLines = new HashSet<long>(linesOfSnippetComment.Keys);
var dictionary = new ConcurrentDictionary<string, DfmTagNameResolveResult>(StringComparer.OrdinalIgnoreCase);
foreach (var snippetCommentsInPair in linesOfSnippetComment.GroupBy(kvp => kvp.Value))
{
DfmTagNameResolveResult tagResolveResult;
var lineNumbers = snippetCommentsInPair.Select(line => line.Key).OrderBy(line => line).ToList();
if (lineNumbers.Count == 2)
{
tagResolveResult = new DfmTagNameResolveResult
{
IsSuccessful = true,
StartLine = lineNumbers[0] + 1,
EndLine = lineNumbers[1] - 1,
ExcludesLines = excludedLines
};
}
else
{
tagResolveResult = new DfmTagNameResolveResult
{
IsSuccessful = false,
ErrorMessage = lineNumbers.Count == 1
? $"Tag name {snippetCommentsInPair.Key} is not closed"
: $"Tag name {snippetCommentsInPair.Key} occurs {lineNumbers.Count} times"
};
}
dictionary.TryAdd(snippetCommentsInPair.Key, tagResolveResult);
}
return dictionary;
}));
DfmTagNameResolveResult resolveResult;
var tagNamesDictionary = lazyResolveResults.Value;
return (tagNamesDictionary.TryGetValue(tagName, out resolveResult) || tagNamesDictionary.TryGetValue($"snippet{tagName}", out resolveResult))
? resolveResult
: new DfmTagNameResolveResult { IsSuccessful = false, ErrorMessage = $"Tag name {tagName} is not found" };
}