比较两个以逗号分隔的字符串匹配的最短代码是什么?

以下称为UserCanAccessThisPage的方法基于以下逻辑:每个用户和每个页面都有一个组列表。 如果其中任何一个匹配,则用户可以访问该页面。

下面的代码做了我想要的,但我的解决方案是C#1 (或C#2,至少我没有使用ArrayList)。

任何人都可以重构这一点,这样更简单,例如使用lambdas来消除这两种方法吗? 我只是无法获得语法来做到这一点。

using System; using System.Collections.Generic; using System.Linq; namespace TestCompare2343 { class Program { static void Main(string[] args) { string anonymousUserAccessGroups = "loggedOutUsers"; string normalUserAccessGroups = "loggedInUsers, members"; string developerUserAccessGroups = "loggedInUsers, members, administrators, developers"; string loginPageAccessGroups = "loggedOutUsers"; string logoutPageAccessGroups = "loggedInUsers"; string memberInfoPageAccessGroups = "members"; string devPageAccessGroups = "developers"; //test anonymousUser Console.WriteLine(StringHelpers.UserCanAccessThisPage(anonymousUserAccessGroups, loginPageAccessGroups)); Console.WriteLine(StringHelpers.UserCanAccessThisPage(anonymousUserAccessGroups, logoutPageAccessGroups)); Console.WriteLine(StringHelpers.UserCanAccessThisPage(anonymousUserAccessGroups, memberInfoPageAccessGroups)); Console.WriteLine(StringHelpers.UserCanAccessThisPage(anonymousUserAccessGroups, devPageAccessGroups)); Console.WriteLine("---"); //test anonymousUser Console.WriteLine(StringHelpers.UserCanAccessThisPage(normalUserAccessGroups, loginPageAccessGroups)); Console.WriteLine(StringHelpers.UserCanAccessThisPage(normalUserAccessGroups, logoutPageAccessGroups)); Console.WriteLine(StringHelpers.UserCanAccessThisPage(normalUserAccessGroups, memberInfoPageAccessGroups)); Console.WriteLine(StringHelpers.UserCanAccessThisPage(normalUserAccessGroups, devPageAccessGroups)); Console.WriteLine("---"); //test anonymousUser Console.WriteLine(StringHelpers.UserCanAccessThisPage(developerUserAccessGroups, loginPageAccessGroups)); Console.WriteLine(StringHelpers.UserCanAccessThisPage(developerUserAccessGroups, logoutPageAccessGroups)); Console.WriteLine(StringHelpers.UserCanAccessThisPage(developerUserAccessGroups, memberInfoPageAccessGroups)); Console.WriteLine(StringHelpers.UserCanAccessThisPage(developerUserAccessGroups, devPageAccessGroups)); Console.WriteLine("---"); Console.ReadLine(); } } public class StringHelpers { public static bool UserCanAccessThisPage(string userAccessGroups, string pageItemAccessGroups) { List userAccessGroupsList = StringHelpers.SplitAndTrimCommaDelimitedString(userAccessGroups); List pageItemAccessGroupList = StringHelpers.SplitAndTrimCommaDelimitedString(pageItemAccessGroups); foreach (string userAccessGroup in userAccessGroupsList) { foreach (string pageItemAccessGroup in pageItemAccessGroupList) { if (userAccessGroup == pageItemAccessGroup) return true; } } return false; } public static List SplitAndTrimCommaDelimitedString(string line) { List piecesWithSpaces = line.Split(',').ToList(); List piecesWithoutSpaces = new List(); foreach (string pieceWithSpace in piecesWithSpaces) { piecesWithoutSpaces.Add(pieceWithSpace.Trim()); } return piecesWithoutSpaces; } } } 

回答:

Fredrik有最简洁的代码解决了上面的原始任务:

 public static bool UserCanAccessThisPage(string userAccessGroups, string pageItemAccessGroups) { return userAccessGroups .Split(',') .Select(s => s.Trim()) .Contains(pageItemAccessGroups); } 

我用过的代码:

但Shaul认为PageItems也可以有多个条目是正确的,例如“成员,客人”,所以我实际上使用了Shaul的代码:

 public static bool UserCanAccessThisPage(string userAccessGroups, string pageItemAccessGroups) { List userAccessGroupsList = StringHelpers.SplitAndTrimCommaDelimitedString(userAccessGroups); List pageItemAccessGroupList = StringHelpers.SplitAndTrimCommaDelimitedString(pageItemAccessGroups); return userAccessGroupsList.Any(userAccessGroup => pageItemAccessGroupList.Any(pageItemAccessGroup => userAccessGroup == pageItemAccessGroup)); } public static List SplitAndTrimCommaDelimitedString(string line) { return line.Split(',').Select(s => s.Trim()).ToList(); } 

StringHelpers看起来像这样:

 public class StringHelpers { private static readonly char[] separator = ",".ToCharArray(); public static bool UserCanAccessThisPage( string userAccessGroups, string pageItemAccessGroups) { return userAccessGroups .Split(separator) // split on comma .Select(s => s.Trim()) // trim elements .Contains(pageItemAccessGroups); // match } } 

好的,你说你想要紧凑……! 🙂

 public static bool UserCanAccessThisPage(string userAccessGroups, string pageItemAccessGroups) { List userAccessGroupsList = StringHelpers.SplitAndTrimCommaDelimitedString(userAccessGroups); List pageItemAccessGroupList = StringHelpers.SplitAndTrimCommaDelimitedString(pageItemAccessGroups); return userAccessGroupsList.Any(userAccessGroup => pageItemAccessGroupList.Any(pageItemAccessGroup => userAccessGroup == pageItemAccessGroup)); // or: // return userAccessGroupsList.Any(userAccessGroup => pageItemAccessGroupList.Contains(userAccessGroup)); } public static List SplitAndTrimCommaDelimitedString(string line) { return line.Split(',').Select(s => s.Trim()).ToList(); } 

一旦有了两个IEnumerable ,就可以使用Intersect函数:

 return userGroups.Intersect(pageGroups).Count > 0; 

这是为了您需要页面上用户的完整权限列表。
但是,我会选择Shaul的例子: Any函数更快,它应该在第一场比赛时停止。

 public static bool UserCanAccessThisPage( string userAccessGroups, string pageItemAccessGroups) { HashSet u = new HashSet( userAccessGroups.Split(',').Select(x => x.Trim())); return u.Overlaps(pageItemAccessGroups.Split(',').Select(x => x.Trim())); } 

喜欢的东西(抱歉没有IDE)

 public static bool UserCanAccessThisPage(string userAccessGroups, string pageItemAccessGroups) { List userAccessGroupsList = StringHelpers.SplitAndTrimCommaDelimitedString(userAccessGroups); List pageItemAccessGroupList = StringHelpers.SplitAndTrimCommaDelimitedString(pageItemAccessGroups); return userAccessGroupsList.Where( uag => pageItemAccessGroupList.Contains(uag)).Count > 0; } public static List SplitAndTrimCommaDelimitedString(string line) { return line.Split(',').Select(s => s.Trim()).ToList(); } 

我真的没有看到它有两个方法的大问题,因为function很好地分开,但我想你可以将代码从内联的第二种方法转移到第一种方法,如果你真的想要的话。