【问题标题】:Compare arrays or other methods [closed]比较数组或其他方法[关闭]
【发布时间】:2013-12-18 11:03:44
【问题描述】:

我对 C# 还很陌生。我一直在寻找一种简单的方法来检查数组中的所有值是否介于或等于下限和上限之间,这些对于数组中的每个元素都是不同的。我还对每个数据集进行了多次评估。这是我当前使用的方法,效果很好,但我希望使用更有效的方法。似乎一个 pedic 方法似乎符合我的需要,但我不确定如何让它发挥作用。

最后还有几个小问题由此引出。

我使用的数组通常有大约 20 个元素,而不是这里的 5 个。

已更改列名以保护无辜者...

int x;
bool failed;
double [] myArray = new double [5];

for(int a = 0;a<= Convert.ToInt32(temp.Compute("Max(Col1)",string.Empty));a++)
{
    failed = false;

    IEnumerable<DataRow>rows = temp.AsEnumerable()
                                   .Where(r=>r.Field<int>("Col1") == a
                                     && r.Field<int>("Col2") > 0
                                     && r.Field<int>("Col2") < 2000
                                     && r.Field<decimal>("Col3") > 0
                                     && r.Field<decimal>("Col3") < 1000
                                   );

    myArray[0] = rows.AsEnumerable().ToList().Count;
    myArray[1] = rows.AsEnumerable().Sum(row => row.Field<int>("Col4"));
    myArray[2] = rows.AsEnumerable().Average(row => row.Field<int>("Col4"));
    myArray[3] = rows.AsEnumerable().Max(row => row.Field<int>("Col5"));
    myArray[4] = rows.AsEnumerable().Min(row => row.Field<int>("Col5"));

    //CHECK 1 ////////////////////////////////////////
    double [] lowerLimit1 = {0,10,0,50000,2};
    double[] upperLimit1 = {6000,20,0.75,80000,2};
    for(int d = 0;d< myArray.Length;d++)
    {
        if(myArray[d] >= lowerLimit1[d] && myArray[d] <= upperLimit1[d])
        {
            x++;
        };
    };
    if(x > myArray.Length)
    {
        failed = true;
        dt = rows.CopyToDataTable<DataRow>();
    };
    //CHECK 2 ////////////////////////////////////////
    if(! failed)
    {
        x = 0;
        double [] lowerLimit2 = {6000,50,0,30000,2};
        double[] upperLimit2 = {6000,10,0.75,50000,2};
        for(int d = 0;d< myArray.Length;d++)
        {
            if(myArray[d] >= lowerLimit2[d] && myArray[d] <= upperLimit2[d])
            {
                x++;
            };
        };
        if(x > myArray.Length)
        {
            failed = true;
            dt = rows.CopyToDataTable<DataRow>();
        };
    };
    //CHECK 3 ////////////////////////////////////////
    if(! failed)
    {
        x = 0;
        double [] lowerLimit3 = {4000,15,0,50000,2};
        double[] upperLimit3 = {5000,20,0.75,80000};
        for(int d = 0;d< myArray.Length;d++)
        {
            if(myArray[d] >= lowerLimit3[d] && myArray[d] <= upperLimit3[d])
            {
                x++;
            };
        };
        if(x > myArray.Length)
        {
            failed = true;
            dt = rows.CopyToDataTable<DataRow>();
        };
    };

};  //END LOOP
if(failed)
{
    // Do stuff and things
};

还有一种方法可以在不重新创建数据行对象的情况下执行以下操作吗?这给出了意外符号“Where”的错误。

myArray[4] = rows.AsEnumerable().Min(row => row.Field<int>("Col1") Where row.Field<int>("Col3") == 10);

我正在尝试实现以下,但是使用数据表比较慢,这就是我使用上述方法的原因。

myArray[4] = Convert.ToInt32(temp.Compute("Min(Col1)","Col3 = 10"));

最后,有没有办法在没有循环的情况下重新填充数组,我尝试了 array.Dispose() 和 array = null 但它们不起作用。例如

double [] lowerLimit = {4000,15,0,50000,2};
double[] upperLimit = {5000,20,0.75,80000};

// 重新填充显然不起作用的数组。

lowerLimit = {6000,50,0,30000,2};
upperLimit = {7000,60,0.75,50000,2};

这比下面的代码更整洁,或者像上面的代码一样使用多个数组,因为在使用中,数组中通常有 20+ 个元素。

lowerLimit[0] = 6000, upperLimit[0] = 7000;
lowerLimit[1] = 50, upperLimit[1] = 60;
lowerLimit[2] = 0, upperLimit[2] = 0.75;
lowerLimit[3] = 30000, upperLimit[3] = 50000;
lowerLimit[4] = 2, upperLimit[4] = 2;

【问题讨论】:

  • 我不清楚你的问题是什么。您能否尝试将代码减少到重现您遇到的问题以及预期的输入和输出所需的最低限度?
  • 嗨,很抱歉造成混乱。上面的代码没有任何问题,我只是在寻找一种方法来减少执行任务所需的代码量,并希望减少运行代码所花费的时间,这只是检查多个值是否在上限和下限。我只对 //Check 1,//Check2 等之间的内容真正感兴趣,我添加了其余部分,希望能够理解我想要实现的目标。谢谢。
  • 这应该会继续codereview.stackexchange.com
  • 我发现这段代码真的很难阅读。 myArray[0] 是计数,myArray[1] 是总和,myArray[2] 是平均值,等等。难道你不能用有意义的参数创建一个类吗?
  • @dav_i 的观点是,如果你能简洁地表达你想要做的事情,你更有可能得到答案。什么应该进去,什么应该出来。如果您必须在精神上解析如此多的嵌套代码以尝试在提出改进建议之前找出意图,那么回答是令人反感的。您似乎也在下半部分提出第二个问题。如果您要问两个问题,那么您应该将它们设为两个单独的问题 :) 同样,这只是一般的 StackOverflow 指导,以便您更有可能快速获得有用的答案。

标签: c# arrays linq


【解决方案1】:

1

可以通过使用All 和函数以及Enumerable.Range 函数的组合来执行值检查。

Enumerable.Range(0,myArray.Length)
          .All(x => lowerLimit1[x] <= myArray[x] && myArray[x] <= upperLimit[x]);

如果所有值都在范围内,这将返回 true,当一个值超出范围时,这将返回 false。

如果你经常使用它,请创建一个辅助函数来做。

public static class MyHelperClass {

  public static bool Between(this double value, double min, double max) {
      return min <= value && value <= max;
  }
}

那你就可以了

Enumerable.Range(0,myArray.Length)
          .All(x => myArray[x].Between(lowerLimit[x], upperLimit[x]);

2

替换为:

rows.AsEnumerable().Min(row => row.Field<int>("Col1") Where row.Field<int>("Col3") == 10);

where 放在min 之前

rows.AsEnumerable().Where(row => row.Field<int>("Col3") == 10)
                   .Min(row => row.Field<int>("Col1"));

3

你只需分配一个新数组,

lowerLimit = new double[] {6000,50,0,30000,2};
upperLimit = new double[] {7000,60,0.75,50000,2};

在某些情况下,它可以缩短为 new[] 而不是 new double[],但前提是编译器绝对肯定您的意思。

【讨论】:

  • 谢谢各位大侠的帮助,我想这回答了我的问题。
猜你喜欢
  • 2017-05-05
  • 2017-06-07
  • 2012-01-24
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多