简体   繁体   English

如何在同一个 position 中将多个字符串 Arrays 中的双精度值相加? C#

[英]How do I add up Double Values from multiple String Arrays at the same position? C#

I get Strings like this from my database:我从我的数据库中得到这样的字符串:

NaN#Nan#44.20216139610997#45.35340149990988#45.44329482112824#45.1593428796393#NaN#NaN NaN#Nan#44.20216139610997#45.35340149990988#45.44329482112824#45.1593428796393#NaN#NaN

values = SQLvalues.Split('#'); //produces Array you can see in the picture

字符串数组 (String[] values) (字符串 [] 值)

Going on further with strings until it ends with about 10 "NaN" Strings again.继续使用字符串,直到它再次以大约 10 个“NaN”字符串结尾。

What I am doing now is that I sum up all the values from that one Array.我现在正在做的是总结那个数组中的所有值。

But there will be about 100 more Arrays after this one and I need to add up for example values[8] from this Array with the one at the same position from the next Array.但是在这个之后还会有大约 100 个 Arrays,我需要将此数组中的值 [8] 与下一个数组中相同的 position 相加。

加起来 hope this visualizes better what I need to do希望这可以更好地可视化我需要做的事情

As I am still an apprentice I don´t have much knowledge on all of this.因为我还是个学徒,所以我对这一切都没有太多了解。

I´ve been trying to come with a solution for several hours now but I won´t seem to get anything to work here.我已经尝试了几个小时的解决方案,但我似乎无法在这里工作。

Any help would be great!任何帮助都会很棒!

My Code:我的代码:

String[] values;
String returnString = "";
List<Double> valueList = new List<Double>();

DateTime time = (DateTime)skzAdapterText.MinTambourChangedTime();

DataTable profilData = skzAdapterText.LoadValuesText(time);

int rowCount = profilData.Rows.Count;

for (int i = 0; i < rowCount; i++)
{
    String SQLvalues = (String)profilData.Rows[i][2];

    values = SQLvalues.Split('#');

    double summe = 0;
    int counter = 0;

    foreach (String tmpRow in values)
    {
        Double value;
        if (double.TryParse(tmpRow, NumberStyles.Float | NumberStyles.AllowThousands, 
        CultureInfo.InvariantCulture, out value)
        && !double.IsNaN(value))
        {
            counter++;
            summe = summe + value;
        }
    }

    if (summe != 0 && counter != 0)
        valueList.Add(summe / counter);
}

The basic sum can be reduced like so:基本总和可以这样减少:

values = SQLvalues.Split('#'); 
double sum = values.Where(v => v != "NaN").Select(v => double.Parse(v)).Sum();

For a specific position, say index 8, within many rows:对于特定的 position,例如索引 8,在许多行中:

//Read the data from DB
DataTable profilData = skzAdapterText.LoadValuesText(time);

//parse out the values
var rowValueArrays = // will be a List<double[]>
    profilData.Rows.
    Select(r => r[2].Split('#').Select(v => v == "NaN"?0.0:double.Parse(v)).ToArray()).
    ToList();

// sum the entries at index 8
double sumAt8 = rowValueArrays.Select(r => r[8]).Sum();

You say you are an apprentice, and so the syntax here may be unfamiliar to you and seem difficult to understand.你说你是学徒,所以这里的语法你可能不熟悉,看起来很难理解。 But I want to emphasize the power here.但我想强调这里的力量。 The combination of IEnumerable, lambda expressions, and linq operations reduced the original sample down to two lines of code, and solved the full problem is what is technically three lines (spread out a little for readability). IEnumerable、lambda 表达式和 linq 操作的组合将原始示例减少到两行代码,并解决了技术上三行代码的全部问题(为了便于阅读,稍微展开)。 If I wanted to sacrifice any sense of style or maintainability, we could do it in just one line of code .如果我想牺牲任何风格或可维护性,我们只需一行代码就可以做到

In short, it is well worth your time to learn how to write code this way.简而言之,花时间学习如何以这种方式编写代码是非常值得的。 With practice, reading and writing code this way can become easy and greatly increase your speed and capability as a programmer.通过练习,以这种方式阅读和编写代码可以变得容易,并大大提高您作为程序员的速度和能力。

I also see attempts to compute an average.我还看到了计算平均值的尝试。 Continuing from the end of the previous code:从上一个代码的末尾继续:

int countAt8 = rowValuesArrays.Count(r => r[8] != 0.0);
double average = sumAt8 / countAt8;

Finally, I need to point out delimited data like this in a column is an abuse of the database and very poor practice.最后,我需要指出,像这样在列中分隔数据是对数据库的滥用,也是非常糟糕的做法。 Schemas like this are considered broken , and need to be fixed .像这样的模式被认为是损坏的,需要修复

As you want to sum up the values at the same positions of the arrays, I assume that all these array have the same length.由于您想总结 arrays 相同位置的值,我假设所有这些数组具有相同的长度。 Then first declare the required arrays.然后先声明需要的arrays。 You also must probably calculate the average for each array position, so you also need an array for the counter and the averages.您还必须计算每个数组 position 的平均值,因此您还需要一个用于计数器和平均值的数组。

double[] average = null;
int rowCount = profilData.Rows.Count;

if (rowCount > 0) {
    string[] values = ((string)profilData.Rows[0][2]).Split('#');
    int n = values.Length;
    double[] sum = new double[n];
    double[] counter = new double[n];
    for (int i = 0; i < rowCount; i++) {
        values = ((string)profilData.Rows[i][2]).Split('#');
        for (int j = 0; j < n; j++) {
            if (double.TryParse(values[j], NumberStyles.Float | NumberStyles.AllowThousands,
                CultureInfo.InvariantCulture, out double value) && !double.IsNaN(value)) {
                counter[j]++;
                sum[j] += value;
            }
        }
    }
    average = new double[n];
    for (int i = 0; i < n; i++) {
        if (counter[i] != 0) {
            average[i] = sum[i] / counter[i];
        }
    }
}

You cannot calculate the average while summing up, since you must divide the total sum by the total count.求和时无法计算平均值,因为您必须将总和除以总计数。 Therefore, I added another loop calculating the averages at each array position after the summing phase.因此,我在求和阶段之后添加了另一个循环来计算每个数组 position 的平均值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM