Какой самый короткий код для сравнения двух разделенных запятыми строк на совпадение? - PullRequest
1 голос
/ 14 июля 2009

Метод, названный ниже UserCanAccessThisPage , основан на следующей логике: у каждого пользователя и каждой страницы есть список групп. Если что-либо из этого совпадает, пользователь имеет доступ к странице.

Код ниже делает то, что я хочу, но мое решение очень C # 1 (или C # 2, по крайней мере, я не использовал ArrayList).

Может ли кто-нибудь рефакторинг этого , чтобы он был более простым, например, используя лямбды, чтобы покончить с двумя методами? Я просто не могу получить синтаксис для этого.

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<string> userAccessGroupsList = StringHelpers.SplitAndTrimCommaDelimitedString(userAccessGroups);
            List<string> pageItemAccessGroupList = StringHelpers.SplitAndTrimCommaDelimitedString(pageItemAccessGroups);

            foreach (string userAccessGroup in userAccessGroupsList)
            {
                foreach (string pageItemAccessGroup in pageItemAccessGroupList)
                {
                    if (userAccessGroup == pageItemAccessGroup)
                        return true;
                }
            }

            return false;
        }

        public static List<string> SplitAndTrimCommaDelimitedString(string line)
        {
            List<string> piecesWithSpaces = line.Split(',').ToList<string>();
            List<string> piecesWithoutSpaces = new List<string>();
            foreach (string pieceWithSpace in piecesWithSpaces)
            {
                piecesWithoutSpaces.Add(pieceWithSpace.Trim());
            }
            return piecesWithoutSpaces;
        }
    }
}

Ответ:

У Фредрика был самый лаконичный код, который решал исходную задачу выше:

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

Код, который я использовал:

Но Шауль был прав, предполагая, что PageItems также может иметь несколько записей, например «члены, гости», и поэтому я фактически использовал код Шаула:

public static bool UserCanAccessThisPage(string userAccessGroups, string pageItemAccessGroups) {
  List<string> userAccessGroupsList = StringHelpers.SplitAndTrimCommaDelimitedString(userAccessGroups);
  List<string> pageItemAccessGroupList = StringHelpers.SplitAndTrimCommaDelimitedString(pageItemAccessGroups);
  return userAccessGroupsList.Any(userAccessGroup => pageItemAccessGroupList.Any(pageItemAccessGroup => userAccessGroup == pageItemAccessGroup));
}

public static List<string> SplitAndTrimCommaDelimitedString(string line) {
  return line.Split(',').Select(s => s.Trim()).ToList();
}

Ответы [ 5 ]

5 голосов
/ 14 июля 2009

ОК, вы сказали, что хотите компактный ...! :)

public static bool UserCanAccessThisPage(string userAccessGroups, string pageItemAccessGroups) {
  List<string> userAccessGroupsList = StringHelpers.SplitAndTrimCommaDelimitedString(userAccessGroups);
  List<string> pageItemAccessGroupList = StringHelpers.SplitAndTrimCommaDelimitedString(pageItemAccessGroups);
  return userAccessGroupsList.Any(userAccessGroup => pageItemAccessGroupList.Any(pageItemAccessGroup => userAccessGroup == pageItemAccessGroup));
  // or:
  // return userAccessGroupsList.Any(userAccessGroup => pageItemAccessGroupList.Contains(userAccessGroup));
}

public static List<string> SplitAndTrimCommaDelimitedString(string line) {
  return line.Split(',').Select(s => s.Trim()).ToList();
}
2 голосов
/ 14 июля 2009

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
    }
}
1 голос
/ 14 июля 2009
public static bool UserCanAccessThisPage(
    string userAccessGroups, string pageItemAccessGroups)
{
    HashSet<string> u = new HashSet<string>(
        userAccessGroups.Split(',').Select(x => x.Trim()));
    return u.Overlaps(pageItemAccessGroups.Split(',').Select(x => x.Trim()));
}
1 голос
/ 14 июля 2009

Если у вас есть два IEnumerable<string> с, вы можете использовать функцию Intersect:

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

Это на тот случай, если вам нужен полный список разрешений для пользователя на странице.
Однако я бы пошел с примером Шаула: функция Any работает быстрее, она должна остановиться при первом совпадении.

0 голосов
/ 14 июля 2009

Что-то вроде (извините, нет IDE в руки)

public static bool UserCanAccessThisPage(string userAccessGroups, string pageItemAccessGroups)
{
    List<string> userAccessGroupsList = StringHelpers.SplitAndTrimCommaDelimitedString(userAccessGroups);
    List<string> pageItemAccessGroupList = StringHelpers.SplitAndTrimCommaDelimitedString(pageItemAccessGroups);

    return userAccessGroupsList.Where(
                          uag => pageItemAccessGroupList.Contains(uag)).Count > 0;
}

public static List<string> SplitAndTrimCommaDelimitedString(string line)
{
    return line.Split(',').Select(s => s.Trim()).ToList<string>();
}

Я действительно не вижу большой проблемы с двумя методами, так как функциональность хорошо разделена, но я думаю, что вы можете переместить код из встроенного второго метода в первый, если вы действительно хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...