Вопрос по lambda, c# – Какой самый короткий код для сравнения двух разделенных запятыми строк на совпадение?

1

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

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

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

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;
        }
    }
}
Answer:

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

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

Но Шауль был прав, предполагая, что 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   ответов
1
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()));
}
2

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
    }
}
Я заметил, что оригинальная реализация также разделяет pageItemAccessGroups, но ни один пример данных не содержит запятой, и это никогда не проверяется. Поэтому я применил тест-ориентированный подход; код проходит обозначенный тест; о)
Я не уверен, что это сработает, поскольку pageItemAccessGroups также является строкой, разделенной запятыми, но, как я уже сказал в своем ответе, у меня нет IDE для проверки прямо сейчас.
Хороший улов, я этого не заметил.
5

:)

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();
}
Я думаю, что ваше второе выражение return гораздо более разборчиво, чем первое, и использование Any (о котором я совсем забыл) делает его быстрее, чем мое. Хороший ответ.
0

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>();
}

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

1

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

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

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

Привет, я не знал о функции Intersect () - +1 за то, что научил меня новому трюку! & # X5EA; & # x5D5; & # x5D3; & # x5D4; & # X5E8; & # x5D1; & # x5D4 ;!

Похожие вопросы