.net 从符合复杂条件的字符串列表中获取特定字符串

htzpubme  于 2022-11-19  发布在  .NET
关注(0)|答案(1)|浏览(199)

我有一个对象,它有一个字符串列表,其中每个字符串代表一个地区(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"]

预期的输出应为:输出1 =〉“SE12”,输出2 =〉“SE”,输出3 =〉“SE123456789”,输出=〉“"。
我用了不同的方法,但似乎比我想象的要棘手。
我的方法现在看起来像这样:

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;
}

有什么想法吗?
编辑以了解更多说明:把前两个字母后面的数字看作树视图。第一个数字表示一组状态,第二个表示一个状态,第三代表一个区和第四代表市......等等。我需要得到最具体的地区,我实现了在输入3。但如果列表有前。2个或更多不同的区,那么我需要得到代表国家的数字。2个以上不同的州,那么我需要得到代表州组的数字。2个或更多不同的州组,那么我需要得到代表国家的前2个字母。2或国家代码ex(“SE”,“FI”),那么输出应该是空字符串。

3htmauhk

3htmauhk1#

为了澄清我相信你在寻找什么:您希望找到表示最具体分区的NUTS代码,该分区对列表中的所有分区都是公共的,或者所有其他NUTS代码都是的更一般分区的分区。本质上,在k元树中找到所有叶节点的路径经过的最深节点:
第一个
对此的一个解决方案可能如下所示(给方法起一个好名字有点棘手):

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;
}

相关问题