如何在另一个列表中返回三个最低值的列表

本文关键字:列表 三个 最低值 返回 另一个 | 更新日期: 2023-09-27 18:19:12

如何在另一个列表中返回 3 个最低值的列表。例如,我想像这样获取 3 个最低值:

in_list = [2, 3, 4, 5, 6, 1]

对此:

out_list: [2, 3, n, n, n, 1]

也许是这样的函数:

out_list = function(in_list, 3)?

in_list和输出列表声明如下:

List<string> in_list = new List<string>();
List<string> out_list = new List<string>();

你能帮我为此开发一个 C# 代码吗?可以给出进一步的解释。

如何在另一个列表中返回三个最低值的列表

如果你真的想要那些奇怪的n,有一个简单的解决方案:

public static List<string> Function(List<string> inputList, int max)
{
    var inputIntegers = inputList
        .Select(z => int.Parse(z))
        .ToList();
    var maxAuthorizedValue = inputIntegers
        .OrderBy(z => z)
        .Take(max)
        .Last();
    return inputIntegers
        .Select(z => z <= maxAuthorizedValue ? z.ToString() : "n")
        .ToList();
}
public static void Main(string[] args)
{
    List<string> in_list = new List<string> { "2", "3", "4", "6", "1", "7" };
    var res = Function(in_list, 3);
    Console.Read();
}

对于有关重复项的新要求,您可以限制返回的最大整数数:

public static List<string> Function(List<string> inputList, int max)
{
    var inputIntegers = inputList.Select(z => int.Parse(z)).ToList();
    var maxAuthorizedValue = inputIntegers
        .OrderBy(z => z)
        .Take(max)
        .Last();
    // I don't really like that kind of LINQ query (which modifies some variable
    // inside the Select projection), so a good old for loop would probably
    // be more appropriated
    int returnedItems = 0;
    return inputIntegers.Select(z =>
        {
            return (z <= maxAuthorizedValue && ++returnedItems <= max) ? z.ToString() : "n";
        }).ToList();
}

您需要两个查询,一个用于确定最低项目,另一个用于填充结果列表。您可以使用HashSet来加快速度:

var lowest = new HashSet<String>(in_list
    .Select(s => new { s, val = int.Parse(s) })
    .OrderBy(x => x.val)
    .Take(3)
    .Select(x => x.s));
List<string> out_list = in_list.Select(s => lowest.Contains(s) ? s : "n").ToList();

如果您实际上只想要 3 个并且可能重复,那么这是我想出的最好的:

var lowest = new HashSet<String>(in_list
    .Select(s => new { s, val = int.Parse(s) })
    .Distinct()
    .OrderBy(x => x.val)
    .Take(3)
    .Select(x => x.s));
List<string> out_list = in_list
    .Select((str, index) => new { str, index, value = int.Parse(str) })
    .GroupBy(x => x.str)
    .SelectMany(g => lowest.Contains(g.Key) 
        ?  g.Take(1).Concat(g.Skip(1).Select(x => new { str = "n", x.index, x.value }))
        :  g.Select(x => new { str = "n", x.index, x.value }))
    .OrderBy(x => x.index)
    .Select(x => x.str)
    .ToList();
您可以使用

Aggregate来获取每个元素的Dictionary及其相应的允许出现次数,然后您可以使用这些元素从输入列表中获取值:

public static List<string> GetList(List<string> in_list, int max)
{
    Dictionary<string, int> occurrences = new Dictionary<string, int>();
    int itemsAdded = 0;
    in_list.OrderBy(x => x).Aggregate(occurrences, (list, aggr) =>
    {
        if (itemsAdded++ < max)
        {
            if (occurrences.ContainsKey(aggr))
                occurrences[aggr]++;
            else
                occurrences.Add(aggr, 1);
        }
        return list;
    });
    //occurrences now contains only each required elements 
    //with the number of occurrences allowed of that element
    List<string> out_list = in_list.Select(x =>
    {
        return (occurrences.ContainsKey(x) && occurrences[x]-- > 0 ? x : "n");
    }).ToList();
    return out_list;
}