C# 在统计细分之后构造字符串列表

C# 在统计细分之后构造字符串列表,c#,C#,我正在构建一个函数,通过使用作为参数提供的统计细分来构造字符串列表。我正在寻找一种更优雅、更精确的方法来实现这一点。这是一个工作的例子,我到目前为止。这目前适用于简单案例,但我预计会有更复杂的案例导致问题(数学四舍五入等) 公共静态void StatisticalList() { List statisticalList=新列表(); 整数总数=500; //最终目标是30%的结果列表值为“1” List entry1=newlist(){“30”,“1”}; //最终目标是40%的结果列表值为

我正在构建一个函数,通过使用作为参数提供的统计细分来构造字符串列表。我正在寻找一种更优雅、更精确的方法来实现这一点。这是一个工作的例子,我到目前为止。这目前适用于简单案例,但我预计会有更复杂的案例导致问题(数学四舍五入等)

公共静态void StatisticalList()
{
List statisticalList=新列表();
整数总数=500;
//最终目标是30%的结果列表值为“1”
List entry1=newlist(){“30”,“1”};
//最终目标是40%的结果列表值为“2”
List entry2=newlist(){“40”,“2”};
//最终目标是30%的结果列表值为“3”
List entry3=新列表(){“30”,“3”};
列表容器=新列表(){entry1,entry2,entry3};
foreach(容器中的列表条目)
{
double doub=Convert.ToDouble(条目[0]);
双百分比=doub/100;
double numberOfElements=(double)百分比*总计数;
for(int i=0;i
为了让这个“更优雅”,我会做一些事情。首先,我将创建一个类来表示一个规则,即“目标百分比”和“值”:

然后,我将创建一个方法,该方法接收这些规则的列表以及所需的列表大小,并返回一个填充了值的列表。我在代码中添加了一些逻辑,以便在总数小于或大于100%的情况下调整每个项目的百分比(另一个选项是,如果总数不等于100,则只抛出一个异常)

例如,如果有人添加了3个项目,其中一个是60%,一个是50%,另一个是40%,我们必须调整这些金额(我们不能填写150%)。因此,我所做的是确定我们需要调整的总金额(在本例中为-50),然后,对于每个项目,计算该项目的PercentGoal占总金额的百分比,将其应用于调整金额,并将其应用于规则的PercentGoal(在本例中,60%=40%,50%=33%,40%=27%),然后用这些调整后的百分比填充列表

我还使用
Enumerable.Repeat
将项目添加到列表中,这比循环构造稍微优雅一些

public static List<double> GetStatisticalList(List<StatisticalRule> rules, int totalCount)
{
    List<double> statisticalList = new List<double>();

    // Capture any difference between our total percentages and 100 percent
    var totalPct = rules.Sum(r => r.PercentGoal);
    var pctDiff = 100 - totalPct;

    foreach (var rule in rules)
    {
        // Calculate the percentage of the total this value represents
        var pctOfTotal = rule.PercentGoal / totalPct * 100;

        // Calculate the amount we need to adjust this 
        // percentage by so the totals equal 100
        var pctAdjustment = pctDiff * pctOfTotal / 100;

        // Determine the number of items to add by adding our adjustment to 
        // our percentage goal and applying that percentage to the totalCount
        var numItems = (int) ((rule.PercentGoal + pctAdjustment) / 100 * totalCount);

        // Add the adjusted amount of this value to our list
        statisticalList.AddRange(Enumerable.Repeat(rule.Value, numItems));
    }

    return statisticalList;
}
输出


如果您希望它们都可以兑换成双倍,为什么要使用
列表?您不应该使用
列表
吗?@Rufus L输入是通过文本文件捕获的,因此这些值最初将作为字符串读取,然后进行转换。如果您有文本文件,则这些值以逗号分隔,因此只需读取一行即可。double[]pair=inputline.Split(新字符[]{',})。选择(x=>double.Parse(x))。KeyPairValue keyPair=新的KeyPairValue(对[0],对[1]);
public class StatisticalRule
{
    public double PercentGoal { get; set; }
    public double Value { get; set; }
}
public static List<double> GetStatisticalList(List<StatisticalRule> rules, int totalCount)
{
    List<double> statisticalList = new List<double>();

    // Capture any difference between our total percentages and 100 percent
    var totalPct = rules.Sum(r => r.PercentGoal);
    var pctDiff = 100 - totalPct;

    foreach (var rule in rules)
    {
        // Calculate the percentage of the total this value represents
        var pctOfTotal = rule.PercentGoal / totalPct * 100;

        // Calculate the amount we need to adjust this 
        // percentage by so the totals equal 100
        var pctAdjustment = pctDiff * pctOfTotal / 100;

        // Determine the number of items to add by adding our adjustment to 
        // our percentage goal and applying that percentage to the totalCount
        var numItems = (int) ((rule.PercentGoal + pctAdjustment) / 100 * totalCount);

        // Add the adjusted amount of this value to our list
        statisticalList.AddRange(Enumerable.Repeat(rule.Value, numItems));
    }

    return statisticalList;
}
static void Main()
{
    // Create our rules
    var statRules = new List<StatisticalRule>
    {
        new StatisticalRule {PercentGoal = 30, Value = 1},
        new StatisticalRule {PercentGoal = 40, Value = 2},
        new StatisticalRule {PercentGoal = 30, Value = 3},
    };

    // Get our 500 item stat list with rules applied
    var statList = GetStatisticalList(statRules, 500);

    // Display the statistics
    Console.WriteLine($"Our statistics list contains {statList.Count} items:");
    foreach (var uniqueValue in statList.Distinct())
    {
        var valueCount = statList.Count(i => i == uniqueValue);

        Console.WriteLine(" - Value: {0}, Count: {1}, Percent of Total: {2}%", 
            uniqueValue, valueCount, (double)valueCount / statList.Count * 100);
    }

    Console.Write("\nDone!\nPress any key to continue...");
    Console.ReadKey();
}