【问题标题】:Searching an array based on one of its fields根据其中一个字段搜索数组
【发布时间】:2015-03-03 07:46:19
【问题描述】:

我有一个类数组,类有两个字段:一个字母和一个数字。

我正在寻找一种写作方式:

对于每个包含指定字母的字段,用数字做一些事情。

我知道我可以这样做:

for(int i = 0; i < Array.Length ; i++)
    if(Array[i].letter == 'a') do something with Array[i].number

有没有办法使用 foreach 循环写下来,或者这是正确的方法?

编辑:在我的情况下,“做某事”意味着:(我需要在课堂上使用第三个字段,我们称之为测试,输入 bool 和 3 个 int 变量,x = 0 和 y = 0,以及 z = 我之前计算的一些数字)

if(Array[i].letter == 'a')
    if(Array[i].test == false)
        if(Array[i].number < z) x++;
        else y++;

【问题讨论】:

  • 如果您能澄清“做某事”,我们会更有帮助。是总和、平均还是排除?
  • 您目前的方法有什么问题?这对我来说似乎完全有效
  • 在这里使用 foreach 或 for 没有区别。你有什么问题?这似乎完全有效。还想知道您是否有理由不使用 KeyValuePair 列表或字典?
  • 您有几种方法可以对集合类型进行操作,从简单的迭代循环、并发、LINQ 等...基本上取决于您要做什么。
  • 我想说的是,您可以使用 foreach,但除了可以说是一点点可读性(范围变量)之外,您不会从中获得太多收益。它简洁明了,这是您在这里真正希望的

标签: c# arrays


【解决方案1】:

假设您的班级如下所示:

class MyClass
{
    public int MyNumber { get; set; }
    public char MyLetter { get; set; }
    public bool Test { get; set; }
}

你有一个名为 myListList&lt;MyClass&gt;

如果您想遍历字母为 A 的类的每个实例,您可以使用 LINQ:

foreach (MyClass myClass in myList.Where(c => c.MyLetter == 'A'))
{
    Console.WriteLine("Number: " + myClass.MyNumber);
}

编辑:更新问题的更新示例:

foreach (MyClass myClass in myList.Where(c => c.MyLetter == 'a' && !c.Test))
{
    if (myClass.MyNumber < z)
        x++;
    else
        y++;
}

【讨论】:

  • 使用最后一个迭代变量,记住class是一个关键字。
  • 由于我对这些结构很陌生,你能澄清一下 MyClass 和 myClass 之间的区别吗?
  • @Januszoff 在我的示例中,MyClass 是类的名称,myClass 是包含该类实例的变量的名称。阅读有关 foreach 循环的更多信息here。阅读更多关于课程here
  • @Januszoff 没问题!我添加了一个示例来匹配您更新的问题。
【解决方案2】:

假设您的数组中填充了 MyClass 类型的对象。

foreach(MyClass obj in Array) {
    if(obj.letter == 'a') {
        // do something
    }
}

【讨论】:

    【解决方案3】:

    您可以使用以下内容:

    var newArray = Array.Where(x => x.letter == 'a')
        .Where(x => !x.test)
        .Where(x => x.number < z);
    

    现在您已经拥有了数组中的所有元素(顺便说一句:Array 对您的数组来说是一个非常糟糕的名称)。但是之后您必须使用forforeach 循环新数组。

    编辑:Ofc。你也可以加入你的 where 子句:

    var newArray = Array.Where(x => x.letter == 'a' && !x.test && x.number <z)
    

    但这似乎有点难看,至少在我看来……这取决于你。

    【讨论】:

    • 我以数组名称为例,我在代码中有 8 个。
    • 您应该能够将这些作为 1 个 lambda 表达式加入。 .Where(x => x.letter == 'a' && !x.test && x.number
    【解决方案4】:

    有很多方法可以用 linq 做你想做的事。

    var valids = arrayName.Where(i => i.letter =='a' && !i.test);
    var x = valids.Count(i => i.number < z);
    var y = valids.Count() - x;
    

    但这似乎不像你目前的方法那么清晰......

    使用 foreach 循环将为您提供一个作用域变量,如果方法扩展更多,这可能会有所帮助。

    foreach(var item in arrayName)
        if(item.letter == 'a')
            .....
    

    但是您当前的方法很清楚它正在尝试做什么,并且看起来很容易维护。

    你的变量名有点粗略,但我希望那只是伪代码:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-08
      • 2020-07-11
      • 1970-01-01
      相关资源
      最近更新 更多