private void _addOrUpdateStandartUniformPart(SentenceElement uniformPart, string rowNr) { Debug.Assert(rowNr == UnknownRowNr); var uniformPartElement = All.Find(x => x.Id == uniformPart.Id); if (uniformPartElement != null) return; var uniformPartNewElement = new UniformPart(uniformPart, rowNr, -1, -1); Log.DebugFormat( $"[{Type}]Актуализация: Создание нового ОЧ: Id = {uniformPartNewElement.Id}, Текст = {uniformPartNewElement.Text}"); if (All.Any(x => x.RowNr == rowNr)) { Log.DebugFormat( $"[{Type}]Актуализация: Добавляем ОЧ с Id = {uniformPartNewElement.Id} в ряд с номером '{rowNr}'"); // добавляем его в объект того ряда, куда он входит, если таковых еще нет. if (All.Find(x => x.RowNr == uniformPartNewElement.RowNr && x.Id == uniformPartNewElement.Id) == null) { Items.ToList() .Find(x => x.Values.Select(y => y.RowNr).Contains(rowNr)) .Add(uniformPartNewElement.Order, uniformPartNewElement); } } else { var uniformPartsNewRow = new UniformPartRow {{uniformPartNewElement.Order, uniformPartNewElement}}; Log.DebugFormat($"[{Type}]Актуализация: Сформирован новый ряд ОЧ с номером '{rowNr}'"); // добавляем ряд к результатам Items.Add(uniformPartsNewRow); } }
private void _mergeRows() { if (Items.Count <= 0) return; Log.InfoFormat("Актуализация: Старт алгоритма объединения рядов на текущих активных ЛО"); // Группируем список всех ОЧ по GUID и берем группы, в которых более 1 члена var uniformPartsToMerge = All.GroupBy(grp => grp.GUID).Where(yy => yy.Count() > 1).ToList(); if (!uniformPartsToMerge.Any()) { Log.InfoFormat("Актуализация: Нечего объединять."); return; } //текущая расчетная переменная var upsToMerge = uniformPartsToMerge.First(); while (upsToMerge != null) { var rowsNrsToMerge = upsToMerge.Select(y => y.RowNr).ToList(); Log.InfoFormat("Объединяем ряды: {0}", string.Join("; ", rowsNrsToMerge)); Debug.Assert(rowsNrsToMerge.Distinct().Count() > 1, "Объединение рядов с одним номером тривиально!"); // выясняем какие ОЧ надо обновить var upsToUpdate = All.Where(x => x.RowNr != rowsNrsToMerge.First() && rowsNrsToMerge.Contains(x.RowNr)) .Select(x => x) .ToList(); //апдейтим свойства ОЧ foreach (var up in upsToUpdate) { // всем ОЧ присваиваем номер первого ряда up.RowNr = rowsNrsToMerge.First(); // и апдейтим значения признаков связи var commaUP = upsToUpdate.Find(x => x.FeatureLinkComma > -1); var conjunctionUP = upsToUpdate.Find(x => x.FeatureLinkConjunction > -1); if (commaUP != null) up.FeatureLinkComma = commaUP.FeatureLinkComma; if (conjunctionUP != null) up.FeatureLinkConjunction = conjunctionUP.FeatureLinkConjunction; } // оставляем уникальные ОЧ var uniqueUPsGroups = All.DistinctBy(c => new {c.Id, c.RowNr}).GroupBy(grp => grp.RowNr); Items.Clear(); foreach (var group in uniqueUPsGroups) { var newRow = new UniformPartRow(); foreach (var up in group) newRow.Add(up.Order, up); Items.Add(newRow); } // обновляем расчетную переменную upsToMerge = All.GroupBy(grp => grp.GUID).Where(yy => yy.Count() > 1).FirstOrDefault(); } }
private void _addOrUpdateBaseOrFinalRowsUniformPart(SentenceElement uniformPart, string rowNr, int featureLinkConjunction, int featureLinkComma) { // если ряд неизвестен, то это эквивалентно добавление стандартного ОЧ if (rowNr == UnknownRowNr) { Log.DebugFormat($"[{Type}]Актуализация: ряд неизвестен, добавляем как стандартный ОЧ"); _addOrUpdateStandartUniformPart(uniformPart, rowNr); return; } // когда добавляем ОЧ с наличием признака ряда, то старый надо удалить из ряда "-1" var uniformPartInUnknownRow = All.Find(x => x.Id == uniformPart.Id && x.RowNr == UnknownRowNr); if (rowNr != UnknownRowNr && uniformPartInUnknownRow != null) { Log.DebugFormat( $"[{Type}]Актуализация: удаление существующего ОЧ с Id = {uniformPartInUnknownRow.Id} и рядом {uniformPartInUnknownRow.RowNr}"); RemoveUniformPart(uniformPartInUnknownRow.Id, false); } List<UniformPart> uniformPartElements = new List<UniformPart>(); // если надо обновить инфу об ОЧ во всех рядах (rowNr == string.Empty) if (rowNr == string.Empty) uniformPartElements.AddRange(All.FindAll(x => x.Id == uniformPart.Id)); else // обычная ситуация uniformPartElements = All.FindAll(x => x.Id == uniformPart.Id && x.RowNr == rowNr); // ОЧ с комбинацией Id-RowNr уже существует if (uniformPartElements.Count > 0) { foreach (var uniformPartElement in uniformPartElements) { if ((uniformPartElement.RowNr != rowNr) || (uniformPartElement.RowNr == rowNr) || uniformPartElement.FeatureLinkComma != featureLinkComma || uniformPartElement.FeatureLinkConjunction != featureLinkConjunction) { Log.DebugFormat( $"[{Type}]Возможная актуализация: Обновление ОЧ с Id = {uniformPartElement.Id}, Текст = {uniformPartElement.Text}, Ряд = {rowNr}"); if (rowNr != string.Empty) { uniformPartElement.RowNr = rowNr; Log.Debug($"[{Type}]Обновлен Ряд: {rowNr}"); } if (featureLinkComma != 0) { uniformPartElement.FeatureLinkComma = featureLinkComma; Log.Debug($"[{Type}]Обновлен ПС Запятая: {featureLinkComma}"); } if (featureLinkConjunction != 0) { uniformPartElement.FeatureLinkConjunction = featureLinkConjunction; Log.Debug($"[{Type}]Обновлен ПС Союз: {featureLinkConjunction}"); } } } } // // ОЧ с комбинацией Id-RowNr НЕ существует else { // если надо создать ряд с пустым номером ряда, то расцениваем это как создание ОЧ с № = -1. if (rowNr == string.Empty) rowNr = UnknownRowNr; var uniformPartNewElement = new UniformPart(uniformPart, rowNr, featureLinkConjunction, featureLinkComma); Log.DebugFormat( $"[{Type}]Актуализация: Создание нового ОЧ: Id = {uniformPartNewElement.Id}, Текст = {uniformPartNewElement.Text}"); if (rowNr != string.Empty) { // проверяем, нет ли уже объектов рядов с номером ряда, как у добавляемого if (All.Any(x => x.RowNr == rowNr)) { Log.DebugFormat( $"[{Type}]Актуализация: Добавляем ОЧ с Id = {uniformPartNewElement.Id} в ряд с номером '{rowNr}'"); // добавляем его в объект того ряда, куда он входит, если таковых еще нет. if (All.Find(x => x.RowNr == uniformPartNewElement.RowNr && x.Id == uniformPartNewElement.Id) == null) { Items.ToList() .Find(x => x.Values.Select(y => y.RowNr).Contains(rowNr)) .Add(uniformPartNewElement.Order, uniformPartNewElement); } } else { // если рядов не нашлось, то создаем новый ряд и добавляем туда наш элемент var uniformPartsNewRow = new UniformPartRow { {uniformPartNewElement.Order, uniformPartNewElement} }; Log.DebugFormat($"[{Type}]Актуализация: Сформирован новый ряд ОЧ с номером '{rowNr}'"); // добавляем ряд к результатам Items.Add(uniformPartsNewRow); } } } if (_needToMerge) _mergeRows(); }