如何在另一个列表中返回 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;
}