Получить определенную строку из списка строк, соответствующих сложным критериям

У меня есть объект со списком строк, где каждая строка представляет собой территорию (коды NUTS). бывший.

["SE","SE12","SE124"]

что я пытаюсь сделать, так это получить наиболее общий и наиболее конкретный (я не знаю, имел ли я смысл) я напишу несколько входных примеров и ожидаемый результат, чтобы стало яснее о том, что я иметь в виду.

input1 : ["SE", "SE123", "SE124", "SE123456", "SE123456789"],
input2 : ["SE", "SE2", "SE123", "SE123456", "SE123456789"],
input3 : ["SE", "SE123", "SE123456", "SE123456789"],
input4 : ["SE","FI", "SE2"]

ожидаемый вывод должен быть: output1 => "SE12", output2 => "SE", outptut3 => "SE123456789", output => "".

Я использовал разные подходы, но это оказалось сложнее, чем я думал.

мой метод в настоящее время выглядит так:

 public static string GetSpecificNuts(IList<string> nuts)
{
    var outNuts = "";
    var annNuts = nuts.Distinct().ToList();
    if (annNuts.Any())
    {
        if (annNuts.Count() == 1)
        {
            outNuts = annNuts.SingleOrDefault();
        }
        else
        {
            var grouped = annNuts.GroupBy(n => n.Length).OrderByDescending(n=>n.Key).ToList();
            var highest = grouped.Select(g => g.Key).FirstOrDefault();

            var highestGroup = grouped?.SingleOrDefault(g => g.Key == highest)?.ToList();
            var length = highestGroup?.Count;

            if (length == 1)
            {
                var highestNuts = highestGroup?.SingleOrDefault();
                var contained = grouped?.Where(n => n.Key != highest).SelectMany(g => g.ToList()).Where(s => highestNuts.StartsWith(s)).OrderByDescending(s=>s.Length);
                var firstContained = contained.FirstOrDefault();
                if (!string.IsNullOrWhiteSpace(firstContained))
                {
                    outNuts = firstContained;
                }
            }
            while (length > 1)
            {
                var deducted = new List<string>();
                highestGroup?.ForEach(i => { deducted.Add(i.Length > 2 ? i.Remove(i.Length - 1, 1) : i); });
                var distinct = deducted?.Distinct().ToList();
                length = distinct?.Count;
                highestGroup = distinct;
                if (length == 1)
                {
                    outNuts = distinct?.SingleOrDefault();
                }
            }
        }
    }

    return outNuts;
}

Какие-нибудь мысли?

РЕДАКТИРОВАТЬ ДЛЯ ДОПОЛНИТЕЛЬНОГО ОБЪЯСНЕНИЯ: рассматривайте числа после первых двух букв как древовидное представление. первое число представляет группу штатов, 2-е представляет штат, 3-е представляет округ, 4-е представляет муниципалитеты и так далее. Мне нужно получить наиболее конкретную область, и я достиг этого на input3. но если в списке есть упр. 2 или более разных округов, тогда мне нужно получить число, представляющее штат. Еще 2 разных состояния, тогда мне нужно получить число, представляющее группу состояний. 2 или более разных групп штатов, тогда мне нужно получить первые 2 буквы, которые представляют страну. 2 или коды стран ex ("SE", "FI"), то на выходе должна быть пустая строка.

каковы критерии ожидаемого результата? Можете ли вы предоставить это на английском языке

lets do it 13.11.2022 13:46

Я добавил больше пояснений к вопросу, надеюсь, это прояснит ситуацию.

Mohamad Hammash 13.11.2022 14:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы уточнить, что, по моему мнению, вы ищете: вы хотите найти код NUTS, представляющий наиболее конкретное подразделение, которое либо является общим для всех в списке, либо подразделение, для которого все остальные коды NUTS являются более общим подразделением. По сути, найдите самый глубокий узел в k-арном дереве, через который проходят пути ко всем листовым узлам:

 SE
  \
   5
    \
     7 <-- Most specific in the common branch (SE57)
    / \
   4   2
 SE
  \
   5 
    \
     7
      \
       2 <-- Most specific in the common branch (SE572)

Одним из решений для этого может быть следующее (дать методу хорошее имя немного сложно):

public static string GetDeepestNodeInCommonBranch(IList<string> nutsCodes)
{
    // Build a tree with the depth being the specificity (index in the code) of
    // the country subdivisions and the nodes at each level being the different
    // divisions at that level/specificity (different numbers at the same index).
    
    var levels = nutsCodes.Distinct(StringComparer.OrdinalIgnoreCase)
        .SelectMany(nc => nc.Select((c, i) => new {Character = c, Index = i}))
        .GroupBy(obj => obj.Index)
        // Walk the tree from the top
        .OrderBy(g => g.Key);
    
    var commonDiv = string.Empty;
    foreach (var level in levels)
    {
        var divisions = level.Select(obj => obj.Character).Distinct().ToList();
        // If the tree branches out here, the division at the last level is the
        // most specific division common for all
        if (divisions.Count > 1)
        {
            // Only return full country codes
            return commonDiv.Length >= 2 ? commonDiv : string.Empty;
        }
        commonDiv += divisions.Single();
    }
    return commonDiv;
}

Это именно то, что я ищу! Спасибо, приятель, ты заставил меня почувствовать это: twitter.com/vishalmalvi_/status/1546493087299428352

Mohamad Hammash 13.11.2022 18:15

Другие вопросы по теме