如何计算列分数和时间的总和

时间:2015-10-25 20:29:07

标签: c#

我有一个如下所示的二维数组。 如果我想总结从课程0x0000 = startpoint开始的每个ID的所有时间和得分,并以课程E = endspoint结束。在下面的情况中,对于ID 1,它变为(时间= 190 + 195 + 200 = 585并且得分= 3 + 3 + 4 = 10)和ID 3(时间= 190 + 210 + 160 = 560并且得分= 5 + 4 + 4 = 13)。

我已经想出了以下循环。

I

-

 ID Lesson  Time    Score
    1   C   165 4
    1   E   190 3
    1   H   195 3
    1   I   200 4
    2   A   100 2
    2   B   150 5
    2   D   210 2
    2   E   110 4
    3   D   130 5
    3   E   190 5
    3   H   210 4
    3   I   160 4
    3   J   110 4
    4   E   120 3
    4   H   150 4
    4   J   170 4

3 个答案:

答案 0 :(得分:1)

试试这个:

// this method does the calculations then puts the values in the totalScore and totaltime variables
public void DoCalculations(string[,] data, string id, out int totalScore, out int totalTime)
{
    totalTime = 0;
    totalScore = 0;

    for (int i = 0; i < data.GetLength(0); i++)
    {
        if (data[i, 0] != id) continue;

        // modify this string to contain the lessons between E and I
        if (!"EFGHI".Contains(data[i, 1])) continue;

        // do proper error checking unless you're sure they'll always be integers
        totalTime += int.Parse(data[i, 2]);
        totalScore += int.Parse(data[i, 3]);
    }
}

这是用法示例:

string[,] data = new string[,]
{
    {"1",   "C",   "165", "4"},
    {"1",   "E",   "190", "3"},
    {"1",   "H",   "195", "3"},
    {"1",   "I",   "200", "4"},
    {"2",   "A",   "100", "2"},
    {"2",   "B",   "150", "5"},
    {"2",   "D",   "210", "2"},
    {"2",   "E",   "110", "4"},
    {"3",   "D",   "130", "5"},
    {"3",   "E",   "190", "5"},
    {"3",   "H",   "210", "4"},
    {"3",   "I",   "160", "4"},
    {"3",   "J",   "110", "4"},
    {"4",   "E",   "120", "3"},
    {"4",   "H",   "150", "4"},
    {"4",   "J",   "170", "4"}
};

// will store the total score
int totalScore = 0;
// will store the total time
int totalTime = 0;
// calling the function for the id=3
DoCalculations(data, "3", out totalScore, out totalTime);

Console.WriteLine(totalTime); // will output: 560
Console.WriteLine(totalScore); // will output: 13

答案 1 :(得分:0)

你知道break声明吗?您应该能够创建一个检查条件的条件语句,然后将break;放在其底部,然后退出循环。

答案 2 :(得分:0)

我会尽量避免使用string[,] FILTERED来存储您的数据。您可以轻松地创建强大的数据类型。但是,如果必须使用它,那么我将转换为强数据类型,然后进行计算。

所以,从原始数据开始:

string[,] FILTERED = new string[16, 4]
{
    { "1", "C", "165", "4" },
    { "1", "E", "190", "3" },
    { "1", "H", "195", "3" },
    { "1", "I", "200", "4" },
    { "2", "A", "100", "2" },
    { "2", "B", "150", "5" },
    { "2", "D", "210", "2" },
    { "2", "E", "110", "4" },
    { "3", "D", "130", "5" },
    { "3", "E", "190", "5" },
    { "3", "H", "210", "4" },
    { "3", "I", "160", "4" },
    { "3", "J", "110", "4" },
    { "4", "E", "120", "3" },
    { "4", "H", "150", "4" },
    { "4", "J", "170", "4" },
};

我首先将其转换为强类型数据:

var data = 
    FILTERED
        .Cast<string>()
        .Select((x, n) => new { x, n })
        .GroupBy(xn => xn.n / 4, xn => xn.x)
        .Select(xs => new
        {
            ID = int.Parse(xs.ElementAt(0)),
            Lession = xs.ElementAt(1),
            Time = int.Parse(xs.ElementAt(2)),
            Score = int.Parse(xs.ElementAt(3)),
        });

这给出了:

data

然后我会做这个查询:

var result =
    data
        .GroupBy(x => x.ID)
        .Select(xs => new
        {
            ID = xs.Key,
            Lessions = xs
                .Where(x => x.Lession.Intersect("EFGHI").Any())
                .ToArray(),
        })
        .Select(x => new
        {
            x.ID,
            Time = x.Lessions.Sum(y => y.Time),
            Score = x.Lessions.Sum(y => y.Score),
        })
        .ToArray();

这给了我这个结果:

result

现在,作为替代中间FILTERED数组的替代方法,您可以直接从DataTable获取数据,如下所示:

var data =
    from row in interaction.Rows.Cast<DataRow>()
    select new 
    {
        ID = row.Field<int>(0),
        Lession = row.Field<string>(1),
        Time = row.Field<int>(2),
        Score = row.Field<int>(3),
    };