【问题标题】:Use foreach to loop through list (or array) as sequence of pairs使用 foreach 将列表(或数组)作为对序列进行循环
【发布时间】:2015-09-03 02:39:46
【问题描述】:

我正在创建一个简单的程序,它从 Customers.txt 文件中读取用户名和密码并验证它是否正确。 Customer.txt 的格式是用户名和密码的序列,用逗号分隔(忽略练习的安全问题):

JohnDoe,1234,JaneDoe,5678,...

是否可以创建一个 foreach 循环来遍历 strArray[] 并检查对 {strArray[0], strArray[1]} 然后 {strArray[2],strArray[3]} 等等,看看用户是否放正确的凭据?

private void enter_click_Click(object sender, RoutedEventArgs e)
{
    StreamReader reader1 = new StreamReader("Customers.txt");
    string text = reader1.ReadToEnd();
    reader1.Close();

    string[] Strarray = text.Split(',');
    StreamReader reader2 = new StreamReader("Admin.txt");
    string text2 = reader2.ReadToEnd();
    reader2.Close();

    string[] AdminArray = text2.Split(',');
    if (username_txt.Text == AdminArray[0] && passwordBox1.Password == AdminArray[1])
    {
        AdminPage admin = new AdminPage();
        admin.Activate();
        admin.Show();
        method.CheckDate();
        return;
    }
    if (username_txt.Text == Strarray[0] && passwordBox1.Password == Strarray[1])
        {
            ATM_Screen atm = new ATM_Screen();
            atm.Activate();
            atm.Show();
            method.CheckDate();
            return;
        }

【问题讨论】:

    标签: c# arrays file text foreach


    【解决方案1】:

    是的,您可以这样做:

    var usernames = Strarray.Where((s, i) => { return i % 2 == 0; });
    var passwords = Strarray.Where((s, i) => { return i % 2 != 0; });
    
    var userPasswords = usernames.Zip(passwords, (l, r) => new { username = l, password = r });
    foreach(var userPassword in userPasswords) {
        if (userPassword.username == "rob" && userPassword.password == "robspassword") {
    
        }
    }
    

    根据评论编辑:

    您可以对多个有效凭据执行此操作:

    var allowedCredentials = new List<Tuple<String, String>> { 
        new Tuple<String, String>("Rob", "Robspassword"), 
        new Tuple<String, String> ("SomeoneElse", "SomeoneElsespassword" 
    };
    
    var inputCredentials = new List<string> { "Rob","Robspassword","Rob","Notrobspassword" };
    
    var usernames = inputCredentials.Where((s, i) => { return i % 2 == 0; });
    var passwords = inputCredentials.Where((s, i) => { return i % 2 != 0; });
    
    var userPasswords = usernames.Zip(passwords, (l, r) => new { username = l, password = r });
    foreach(var userPassword in userPasswords) {
        if (allowedCredentials.Any(ac => ac.Item1 == userPassword.username 
               && ac.Item2 == userPassword.password)
        {
            //Valid
        }
    
    }
    

    【讨论】:

    • 感谢您的回答!对于 If 语句,如果将来我有 200 个用户名和密码要循环,我必须为每个用户创建 200 个 If 语句?
    • @mmoretto 一点也不。查看我的编辑了解更多详情
    【解决方案2】:

    使用foreach 很难从序列中获取元素对:

    • 您可以正常遍历序列并记住奇数迭代的第一个元素,对每个偶数迭代执行操作
    • 您可以先使用 LINQ 和索引或 Zip 偶数和奇数一半将序列转换成对。

    收集对方法:

     string name;
     bool even = false;
     foreach(var text in items)
     {
         if (even)
         {
             var password = item;
             // check name, password here 
         }
         else
         { 
             name = text;
         }
         even = !even;
      }
    

    基于 Zip 的方法

      foreach(var pair in items
            .Where((v,id)=>id % 2 == 1) // odd - names
            .Zip(items.Where((v,id)=>id % 2 == 0), // even - passwords
              (name,password)=> new { Name = name, Password = password}))
      {
         // check pair.Name, pair.Password
      }
    

    注意:使用增量为 2 的常规 for 循环会容易得多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-31
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多