检查列表中是否存在值-有比循环更好的方式吗?

3
我可以帮您翻译成中文。以下是需要翻译的内容:

我有以下类数据结构:

public class clsUser
{
    public string userid { get; set; }
    public List<OrgPermission> orgs { get; set; }
}

public class OrgPermission
{
    public string Org { get; set; }
    public string SubOrg {get;set;}
    public List<string> type { get; set; }
}

List<string> type可以具有像“admin”,“user”,“superuser”等值。

因此,每个用户可以具有多个组织-子组合,并具有每个用户角色的多个角色。

用户类中的组织和子组织可以写成这样:56%(这意味着他们可以查看以56开头的所有内容)

我想检查用户是否可以访问类型为“Admin”的页面上的组织-子组合

现在我正在使用循环进行操作,这很有效,就像这样:

foreach (OrgPermission userOrg in user.orgs) {
  if ((ddlOrg.SelectedValue.StartsWith(userOrg.Org.Trim('%'))) && (ddlSubOrg.SelectedValue.StartsWith(userOrg.SubOrg.Trim('%')))) {
    if (userOrg.type.Contains("Admin"))
      btnSubmitToProd.Enabled = true;
    else
      btnSubmitToProd.Enabled = false;
    break; //break out of the loop if the org-sub org match is found
  }
}

有没有更好的方法来消除循环呢?或者我现在的做法是正确的吗?

3个回答

7

听起来你想要:

string orgValue = ddlOrg.SelectedValue;
string subOrgValue = ddlSubOrg.SelectedValue;
btnSubmitToProd = user.orgs
                      .Any(org => orgValue.StartsWith(org.Org.Trim('%')) &&
                                  subOrgValue.StartsWith(org.SubOrg.Trim('%')) &&
                                  org.type.Contains("Admin"));

1
这并没有消除循环,只是将其隐藏在“Any(...)”内部,尽管它看起来比原始代码好得多。 - Sten Petrov
@StenPetrov: 当然没问题 - 但我怀疑这才是原帖作者实际想要的。考虑到需要查找的内容很多,我不认为你能指望完全摆脱循环。 - Jon Skeet
OP所做的事情在许多方面看起来都是错误的,所以你很可能是正确的。+1 - Sten Petrov
@StenPetrov - 我的代码有什么问题吗?我在尝试学习,请解释一下。 - Madam Zu Zu
@MadamZuZu 大小写和命名,硬编码的魔术字符串(“Admin”),可能更适合使用枚举类型,每次访问时都要修剪组织机构,使用 StartsWith 不太合适 - 可能将其预解析为单独的字段更合适,代码冗长(考虑使用 buttonSubmit.Enabled = (user.type.Contains("Admin")))。 - Sten Petrov

4

您可以使用Enumerable.Any方法:

var userIsAdmin = user.orgs.Any(uo => uo.type.Any(uot => uot == "Admin"));

1

我不确定是否使用任何内置方法,但我仍然按照你的方式进行,任何代码最终都将使用foreach逻辑,没有魔法方法。即使使用for代替foreach也会快得多。我仍然支持你的方式,因为它会给你更多的控制权。使用LINQ等任何方法都可以,但for循环是最好的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接