【问题标题】:Comparing values of arrays in C#比较 C# 中数组的值
【发布时间】:2011-06-15 08:09:13
【问题描述】:

我有一个看起来像这样的布尔数组

bool[] responses = new bool[] {true, false, true};

还有两个看起来像这样的类:

public class Person {
  public IList<PersonDetail> PersonDetails
}

public class PersonDetail {
  public bool   Correct { get; set; }
}

PersonDetails
 >> PersonDetail[0].correct = true
 >> PersonDetail[1].correct = true
 >> PersonDetail[2].correct = false

有没有一种简单的方法可以比较它们以查看每个真/假是否相等? 我试图使用 c# .SequenceEqual 但我不知道如何从中获取数据 将 PersonDetail 类转换成一个序列 xxx,我可以用它来与响应进行比较。

这是我目前所拥有的:

var equal = responses.Select(bool.Parse).SequenceEqual( xxx );

我需要做的是比较以下内容:

responses[0] == PersonDetail[0].correct and
responses[1] == PersonDetail[1].correct and
responses[2] == PersonDetail[2].correct 

所以responses[x] 中的真值应该匹配PersonDetail[x] 中的真值,responses[x] 中的假值应该匹配PersonDetail[x] 中的假值

【问题讨论】:

  • 这里有点混乱。是否要比较 Person 数组是否有重复项?
  • 这当然是 for-loop 领域,我看不出 linq 除了减慢它还能做什么?
  • "我有一个像这样的字符串数组"...不,它是一个布尔数组。

标签: c#


【解决方案1】:

您的代码不是很清楚,但我想您想要执行以下操作:

var isEqual = responses.SequenceEqual(PersonDetail.Select(p=>p.Correct))

【讨论】:

  • 不能进行逻辑 AND/OR 操作,因为它们是 bool 类型?我认为那更快更有效! :)
  • @zenwalker - 我在问题中添加了更多内容。希望它能更好地解释它。谢谢
【解决方案2】:

你可以像这样使用 SequenceEqual

var responses = new [] { true, false, true };
var details = new List<PersonDetail>()
                { new PersonDetail() {Correct = true},
                  new PersonDetail() {Correct = false},
                  new PersonDetail() {Correct = true} };
var person = new Person() { PersonDetails = details };

var equal = responses.SequenceEqual(person.PersonDetails.Select(pd => pd.Correct));

【讨论】:

    【解决方案3】:

    从已经给出的答案中,我尝试了一下并想出了下面的方法,似乎可行 - 请注意,我也是 C# 的新手,所以这是一个有趣的问题。

    正如 JonB 在其中一个答案中指出的那样 - 如果“响应”和“人”的长度不同会发生什么......希望以下内容有所帮助

    class Program
    {       
        static void Main(string[] args)
        {
            bool[] responses = new bool[] { true, false, true };
    
            Person people = new Person();
            people.PersonDetails.Add(new PersonDetail() { Correct = true });
            people.PersonDetails.Add(new PersonDetail() { Correct = false });
            people.PersonDetails.Add(new PersonDetail() { Correct = true });
    
            bool equal = responses.SequenceEqual(people.PersonDetails.Select(P=> P.Correct));
            Console.WriteLine (equal);
        }
    }
    
    public class Person
    {
        public List<PersonDetail> PersonDetails = new List<PersonDetail>();
    }
    
    public class PersonDetail
    {
        public bool Correct;
    }
    

    【讨论】:

      【解决方案4】:

      如果我没看错你的问题,这个 LINQ 会按照你的要求去做。我不确定它是否比简单的 foreach 循环更具可读性,但这不是重点!

      public class Person 
      {
        public IList<PersonDetail> PersonDetails;
      }
      
      public class PersonDetail 
      {
        public bool   Correct;
      }
      
      void Main()
      {
          bool[] responses = new bool[] {true, false, true};
          Person p = new Person();
          p.PersonDetails = new List<PersonDetail>();
          p.PersonDetails.Add(new PersonDetail(){Correct = true});
          p.PersonDetails.Add(new PersonDetail(){Correct = true});
          p.PersonDetails.Add(new PersonDetail(){Correct = false});
      
          //bool allGood = p.PersonDetails.Select((pd, index) => pd.Correct == responses[index]).All(x => x==true);
      
          bool allGood = responses.SequenceEqual(p.PersonDetails.Select(x => x.Correct));
          allGood.Dump(); // LINQpad extension
      }
      

      [编辑 - 好的,现在还早,我忘记了 SequenceEquals,它以更易读的方式做同样的事情。代码已更改以匹配其他人已经回答的内容...]。

      【讨论】:

      • 这都是相对的——我不确定 LINQ 是否比 for 循环更具可读性(如果你不知道 LINQ),但第二个 LINQ 比第一个更具可读性!
      【解决方案5】:

      不是 100% 确定您的代码,但可能:

      var equal = responses.SequenceEqual(Person.PersonDetails.Select(PD =&gt; PD.correct);

      【讨论】:

      • 我在问题中添加了更多内容。希望它能更好地解释它。谢谢
      • 我认为这行不通,因为我的 Person 类在名为 PersonDetails 的列表中包含 PersonDetail 类。我想比较响应的标志是 PersonDetail 类中的一个字段。
      • 感谢您的编辑。当我运行您的建议时,我收到一条错误消息:非静态字段、方法或属性 Person.PersonDetails.get 需要对象引用
      • @czhili,将 Person 替换为您的 Person 变量的名称。
      【解决方案6】:

      你也可以试试这样的:

      IEnumerable<bool> answers = from x in Person.PersonDetails select x.correct;
      bool equal = responses.SequenceEqual(answers)
      

      【讨论】:

        【解决方案7】:

        没有比以下更简单的了:-

          if (person.PersonDetails.Count != responses.Length)
            throw new ArgumentOutOfRangeException("Arrays are different lengths");
          bool result = true;
          for (int i = 0; i < person.PersonDetails.Count; i++)
          {
            if (person.PersonDetails[i].Correct != responses[i])
            {
              result = false;
              break;
            }
          }
        

        地球上的每个程序员都可以阅读它,即使他们从未见过 c#。

        实际上它突出了规范中缺失的方面;如果列表长度不同会怎样?

        【讨论】:

        • 如果 responsesperson.PersonDetails 短,你会得到一个错误,所以它没有解决规范的那个方面。
        • 我不确定“花式”是否真的是编程的目标。当我们真正追求快速完成并且可以被狗阅读的东西时,就会出现壮观的繁荣趋势。
        • @Patrick 我确实提到它突出了规范中缺失的方面。虽然它可以返回一个值,但它应该是真还是假?因为我们不知道错误是否有效。
        • 检查了这个并且它有效。我认为在某个地方可能有一个班轮回答,但这个确实有效:-) 响应和 person.PersonDetails 总是相同的长度。
        • 抱歉,我以为你的意思是它解决了这方面的问题。这肯定会引发问题,因为SequenceEqual 只会返回false
        【解决方案8】:

        对这些项目使用 XOR 而不是 AND 或 OR 运算。如果两项相同,XOR 表将为您提供 0。

        【讨论】:

          猜你喜欢
          • 2013-02-09
          • 1970-01-01
          • 2010-10-17
          • 1970-01-01
          • 2015-07-10
          • 1970-01-01
          • 1970-01-01
          • 2021-11-28
          相关资源
          最近更新 更多