コード例 #1
0
        public static void MakeUniqueNames <T>(
            IEnumerable <T> items,
            IEnumerable <string>?staticNames,
            Func <T, string?> nameFunc,
            Action <T, string, ISet <string>?> nameSetter,
            string defaultName      = "t",
            StringComparer?comparer = null)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }
            if (nameFunc == null)
            {
                throw new ArgumentNullException(nameof(nameFunc));
            }
            if (nameSetter == null)
            {
                throw new ArgumentNullException(nameof(nameSetter));
            }

            MakeUniqueNames(items, staticNames, nameFunc, nameSetter, t =>
            {
                var name = nameFunc(t);
                return(string.IsNullOrEmpty(name) ? defaultName : name !);
            }, comparer);
        }
コード例 #2
0
ファイル: EnumUtil.cs プロジェクト: KK578/Bashi.Core
        /// <summary>
        /// Gets the enum value corresponding to the given string description value.
        /// If an enum member is not found with the provided description, this method will fallback
        /// to <see cref="Enum.Parse{TEnum}(string)"/>.
        /// </summary>
        /// <param name="description">Description or String value of <typeparamref name="T"/> member.</param>
        /// <param name="comparer">Optional string comparer - defaults to <see cref="StringComparer.OrdinalIgnoreCase"/></param>
        /// <typeparam name="T">Enum type to be parsed to.</typeparam>
        /// <returns>Enum member value with the given description</returns>
        public static T ParseWithDescription <T>(string description, StringComparer?comparer = null)
            where T : struct, Enum
        {
            comparer ??= StringComparer.OrdinalIgnoreCase;
            var descriptions = EnumUtil.GetValues <T>().ToDictionary(x => x.GetDescription(), comparer);

            return(descriptions.ContainsKey(description) ? descriptions[description] : Enum.Parse <T>(description));
        }
コード例 #3
0
        internal IEnumerable <IFontInstance> FindAll(string name, CultureInfo culture)
        {
            StringComparer?comparer = StringComparerHelpers.GetCaseInsensitiveStringComparer(culture);

            return(this.instances
                   .Where(x => comparer.Equals(x.Description.FontFamily(culture), name))
                   .ToArray());
        }
コード例 #4
0
 /// <summary>
 /// Constructs a new <see cref="IniFile"></see> instance.
 /// </summary>
 /// <param name="comparer"><see cref="StringComparer"></see> used to compare section and setting
 /// names. If not specified, <see cref="StringComparer.CurrentCultureIgnoreCase"></see> is used
 /// (i.e. names are not case-sensitive).</param>
 /// <param name="boolOptions">Options for interpreting <c>bool</c> values.</param>
 public IniFile(StringComparer?comparer = null, BoolOptions?boolOptions = null)
 {
     Sections         = new Dictionary <string, IniSection>(StringComparer);
     StringComparer   = comparer ?? StringComparer.CurrentCultureIgnoreCase;
     BoolOptions      = boolOptions ?? new BoolOptions();
     Comments         = new();
     CommentCharacter = ';';
 }
コード例 #5
0
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 /// <param name="stringComparer">If not provided, <see cref="StringComparer.OrdinalIgnoreCase"/>.</param>
 public CliParserConfig(StringComparer?stringComparer = null, string defaultShortPrefix = "-", string defaultLongPrefix = "--", string shortHelpSwitch = "-?", string longHelpSwitch = "--help")
 {
     StringComparer     = stringComparer ?? StringComparer.OrdinalIgnoreCase;
     IsCaseSensitive    = StringComparer.Compare("a", "A") != 0;          // If they compare as the same, that's case insensitive. If they're different, case sensitive.
     DefaultShortPrefix = defaultShortPrefix;
     DefaultLongPrefix  = defaultLongPrefix;
     ShortHelpSwitch    = shortHelpSwitch;
     LongHelpSwitch     = longHelpSwitch;
 }
コード例 #6
0
 protected void AssertEqual(
     IEnumerable <string> expectedNames,
     IEnumerable <string> actualNames,
     StringComparer?stringComparer = null)
 {
     stringComparer ??= StringComparer.Ordinal;
     Assert.Equal(
         new SortedSet <string>(expectedNames, stringComparer),
         new SortedSet <string>(actualNames, stringComparer),
         stringComparer);
 }
コード例 #7
0
        public static TestableFileSystem CreateForExistingPaths(
            IEnumerable <string> existingPaths,
            StringComparer?comparer = null
            )
        {
            comparer ??= StringComparer.OrdinalIgnoreCase;
            var set = new HashSet <string>(existingPaths, comparer);

            return(new TestableFileSystem()
            {
                FileExistsFunc = filePath => set.Contains(filePath)
            });
        }
コード例 #8
0
        private void CreateStringComparer()
        {
            bool caseInsensitive = Options?.PropertyNameCaseInsensitive == true;

            if (caseInsensitive)
            {
                _stringComparer = StringComparer.OrdinalIgnoreCase;
            }
            else
            {
                _stringComparer = StringComparer.Ordinal;
            }
        }
コード例 #9
0
        /// <inheritdoc/>
        public bool Equals(FontFamily?other)
        {
            if (other is null)
            {
                return(false);
            }

            StringComparer?comparer = StringComparerHelpers.GetCaseInsensitiveStringComparer(this.Culture);

            return(this.collection == other.collection &&
                   this.Culture == other.Culture &&
                   this.DefaultStyle == other.DefaultStyle &&
                   this.AvailableStyles.SequenceEqual(other.AvailableStyles) &&
                   comparer.Equals(this.Name, other.Name));
        }
コード例 #10
0
 /// <summary>
 /// Constructs a <see cref="BoolOptions"></see> instance.
 /// </summary>
 /// <param name="comparer">Specifies the string comparer used to compare strings.
 /// If not supplied, <c>StringComparer.CurrentCultureIgnoreCase</c> is used.</param>
 public BoolOptions(StringComparer?comparer = null)
 {
     BoolStringLookup = new Dictionary <string, bool>(comparer ?? StringComparer.CurrentCultureIgnoreCase)
     {
         [TrueString]  = true,
         [FalseString] = false,
         ["yes"]       = true,
         ["no"]        = false,
         ["on"]        = true,
         ["off"]       = false,
         ["1"]         = true,
         ["0"]         = false,
     };
     NonZeroNumbersAreTrue = true;
 }
コード例 #11
0
        private bool TryFindInternal(string fontFamily, CultureInfo culture, [NotNullWhen(true)] out FontFamily?family)
        {
            StringComparer?comparer = StringComparerHelpers.GetCaseInsensitiveStringComparer(culture);

            family = null !; // make the compiler shutup

            string?familyName = this.instances
                                .Select(x => x.Description.FontFamily(culture))
                                .FirstOrDefault(x => comparer.Equals(x, fontFamily));

            if (familyName == null)
            {
                return(false);
            }

            family = new FontFamily(familyName, this, culture);
            return(true);
        }
コード例 #12
0
 public static void MakeUniqueNames <T>(
     IEnumerable <T> items,
     IEnumerable <string>?staticNames,
     Func <T, string?> nameFunc,
     Action <T, string, ISet <string>?> nameSetter,
     Func <T, string?> defaultName,
     StringComparer?comparer = null)
 {
     if (staticNames != null)
     {
         var staticHash = new HashSet <string>(staticNames, comparer);
         MakeUniqueNames(items, null, (n, a) => !staticHash.Contains(n), nameFunc, nameSetter, defaultName, comparer);
     }
     else
     {
         MakeUniqueNames(items, null, (n, a) => true, nameFunc, nameSetter, defaultName, comparer);
     }
 }
コード例 #13
0
        /// <summary>
        /// Updates one dictionary from another.
        /// </summary>
        public static Dictionary <string, T>?UpdateFrom <T>(
            this Dictionary <string, T>?destination,
            Dictionary <string, T>?source,
            StringComparer?comparer)
        {
            if (source == null)
            {
                return(null);
            }

            if (destination != null && !Equals(destination.Comparer, comparer))
            {
                destination = null;
            }
            if (destination != null)
            {
                destination.Clear();
            }
            else
            {
                destination = new Dictionary <string, T>(comparer);
            }

            foreach (var item in source)
            {
                if (String.IsNullOrEmpty(item.Key))
                {
                    continue;
                }

                if (destination.ContainsKey(item.Key))
                {
                    destination[item.Key] = item.Value;
                }
                else
                {
                    destination.Add(item.Key, item.Value);
                }
            }

            return(destination);
        }
コード例 #14
0
ファイル: Matcher.cs プロジェクト: kjhf/SplatTag
        /// <summary>
        /// Get if this collection matches a second by the transformed names.
        /// Matches by Ordinal by default.
        /// </summary>
        /// <remarks>
        /// Highly optimised method as this is called literally millions of times during matching
        /// </remarks>
        public static bool TransformedNamesMatch(this IReadOnlyCollection <Name> first, IReadOnlyCollection <Name> second, StringComparer?stringComparison = null)
        {
            int firstCount  = first.Count;
            int secondCount = second.Count;

            if (firstCount == 0)
            {
                return(false);
            }
            else if (secondCount == 0)
            {
                return(false);
            }
            else
            {
                stringComparison ??= StringComparer.OrdinalIgnoreCase;

                if (firstCount == 1 && secondCount == 1)
                {
                    return(stringComparison.Equals(first.First().Transformed, second.First().Transformed));
                }
                else if (firstCount == 1)
                {
                    return(second.Select(n => n.Transformed).Contains(first.First().Transformed, stringComparison));
                }
                else if (secondCount == 1)
                {
                    return(first.Select(n => n.Transformed).Contains(second.First().Transformed, stringComparison));
                }
                else
                {
                    return(first.Select(n => n.Transformed).Intersect(second.Select(n => n.Transformed), stringComparison).Any());
                }
            }
        }
コード例 #15
0
        /// <inheritdoc />
        public override int GetHashCode()
        {
            StringComparer?comparer = StringComparerHelpers.GetCaseInsensitiveStringComparer(this.Culture);

            return(HashCode.Combine(this.collection, this.Culture, this.DefaultStyle, this.AvailableStyles) ^ comparer.GetHashCode(this.Name));
        }
コード例 #16
0
ファイル: Matcher.cs プロジェクト: kjhf/SplatTag
        /// <summary>
        /// Get if any matches between <see cref="string"/>s of first and second.
        /// Matches by OrdinalIgnoreCase by default.
        /// </summary>
        public static bool StringMatch(this IReadOnlyCollection <string> first, IReadOnlyCollection <string> second, StringComparer?stringComparison = null)
        {
            if (first.Count == 0 || second.Count == 0)
            {
                return(false);
            }

            stringComparison ??= StringComparer.OrdinalIgnoreCase;
            if (first.Count == 1)
            {
                return((second.Count == 1)
          ? stringComparison.Equals(first.First(), second.First())
          : second.Contains(first.First(), stringComparison));
            }
            else if (second.Count == 1)
            {
                return(first.Contains(second.First(), stringComparison));
            }
            else if (first.Count > 4 || second.Count > 4)
            {
                return(first.Intersect(second, stringComparison).Any());
            }
            else
            {
                foreach (var obj in first)
                {
                    if (second.Contains(obj, stringComparison))
                    {
                        return(true);
                    }
                }
                return(false);
            }
        }
コード例 #17
0
        public static void MakeUniqueNames <T>(
            IEnumerable <T> items,
            ISet <string>?namesParameter,
            Func <string, ISet <string>?, bool> validatorFunc,
            Func <T, string?> nameFunc,
            Action <T, string, ISet <string>?> nameSetter,
            Func <T, string?> defaultName,
            StringComparer?comparer = null)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }
            if (validatorFunc == null)
            {
                throw new ArgumentNullException(nameof(validatorFunc));
            }
            if (nameFunc == null)
            {
                throw new ArgumentNullException(nameof(nameFunc));
            }
            if (nameSetter == null)
            {
                throw new ArgumentNullException(nameof(nameSetter));
            }
            if (defaultName == null)
            {
                throw new ArgumentNullException(nameof(defaultName));
            }

            HashSet <string>?        currentNames    = null;
            Dictionary <string, int>?currentCounters = null;

            foreach (var item in items)
            {
                var name = nameFunc(item);
                if (!string.IsNullOrEmpty(name) && currentNames?.Contains(name !) != true && validatorFunc(name !, namesParameter))
                {
                    if (currentNames == null)
                    {
                        currentNames = new HashSet <string>(comparer);
                    }
                    currentNames.Add(name !);
                    nameSetter(item, name !, namesParameter);
                    continue;
                }

                if (currentNames == null)
                {
                    currentNames = new HashSet <string>(comparer);
                }
                if (currentCounters == null)
                {
                    currentCounters = new Dictionary <string, int>(comparer);
                }

                name = defaultName(item);

                if (string.IsNullOrEmpty(name))
                {
                    name = nameFunc(item);
                }
                if (string.IsNullOrEmpty(name))
                {
                    name = "t";
                }

                var digitCount = 0;
                while (char.IsDigit(name ![name.Length - 1 - digitCount]))
コード例 #18
0
        internal static IReadOnlyDictionary <string, JToken> ToJTokenDictionary(this JToken token, StringComparer?comparaer = null, string?propertyName = null)
        {
            Dictionary <string, JToken> result = new Dictionary <string, JToken>(comparaer ?? StringComparer.Ordinal);

            foreach (JProperty property in token.PropertiesOf(propertyName))
            {
                result[property.Name] = property.Value;
            }

            return(result);
        }
コード例 #19
0
        internal static IReadOnlyDictionary <string, string> ToStringDictionary(this JToken token, StringComparer?comparer = null, string?propertyName = null)
        {
            Dictionary <string, string> result = new Dictionary <string, string>(comparer ?? StringComparer.Ordinal);

            foreach (JProperty property in token.PropertiesOf(propertyName))
            {
                if (property.Value == null || property.Value.Type != JTokenType.String)
                {
                    continue;
                }

                result[property.Name] = property.Value.ToString();
            }

            return(result);
        }
コード例 #20
0
ファイル: Matcher.cs プロジェクト: kjhf/SplatTag
        /// <summary>
        /// Count matches between <see cref="Name"/>s of first and second.
        /// Matches by Ordinal Ignore Case by default.
        /// </summary>
        public static int NamesMatchCount(IReadOnlyCollection <Name> first, IReadOnlyCollection <Name> second, StringComparer?stringComparison = null)
        {
            if (first.Count == 0 || second.Count == 0)
            {
                return(0);
            }

            stringComparison ??= StringComparer.OrdinalIgnoreCase;
            if (first.Count == 1)
            {
                return((second.Count == 1)
          ? stringComparison.Equals(first.First().Value, second.First().Value) ? 1 : 0
          : second.Select(n => n.Value).Contains(first.First().Value, stringComparison) ? 1 : 0);
            }
            else if (second.Count == 1)
            {
                return(first.Select(n => n.Value).Contains(second.First().Value, stringComparison) ? 1 : 0);
            }
            else
            {
                return(first.Select(n => n.Value).Intersect(second.Select(n => n.Value), stringComparison).Count());
            }
        }
コード例 #21
0
ファイル: TinyString.cs プロジェクト: KK578/Bashi.Core
 /// <summary>
 /// Initializes a new instance of the <see cref="TinyString"/> class.
 /// </summary>
 /// <param name="value">Given value for this instance.</param>
 /// <param name="comparer">Comparer to use for equality checks on the underlying string.</param>
 protected TinyString(string value, StringComparer?comparer = default)
     : base(value)
 {
     this.comparer = comparer ?? StringComparer.OrdinalIgnoreCase;
 }
コード例 #22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TextPrompt{T}"/> class.
 /// </summary>
 /// <param name="prompt">The prompt markup text.</param>
 /// <param name="comparer">The comparer used for choices.</param>
 public TextPrompt(string prompt, StringComparer?comparer = null)
 {
     _prompt   = prompt;
     _comparer = comparer;
 }
コード例 #23
0
        public static void MakeUniqueNames <T>(
            IEnumerable <T> items,
            Func <string, bool> validatorFunc,
            Func <T, string?> nameFunc,
            Action <T, string> nameSetter,
            Func <T, string?> defaultName,
            StringComparer?comparer = null)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }
            if (validatorFunc == null)
            {
                throw new ArgumentNullException(nameof(validatorFunc));
            }
            if (nameFunc == null)
            {
                throw new ArgumentNullException(nameof(nameFunc));
            }
            if (nameSetter == null)
            {
                throw new ArgumentNullException(nameof(nameSetter));
            }
            if (defaultName == null)
            {
                throw new ArgumentNullException(nameof(defaultName));
            }

            var duplicates = items.ToLookup(i => nameFunc(i) ?? string.Empty, comparer);

            if (duplicates.Count == 0)
            {
                return;
            }

            var currentNames    = new HashSet <string>(comparer);
            var currentCounters = new Dictionary <string, int>(comparer);

            foreach (var pair in duplicates)
            {
                var groupItems = pair.ToArray();

                if (pair.Key != string.Empty && groupItems.Length == 1 && !currentNames.Contains(pair.Key) && validatorFunc(pair.Key))
                {
                    currentNames.Add(pair.Key);
                    nameSetter(groupItems[0], pair.Key);
                    continue;
                }

                foreach (var groupItem in groupItems)
                {
                    string?name = defaultName(groupItem);

                    if (name.IsNullOrEmpty())
                    {
                        name = nameFunc(groupItem);
                    }
                    if (name.IsNullOrEmpty())
                    {
                        name = "t";
                    }

                    var digitCount = 0;
                    while (char.IsDigit(name[name.Length - 1 - digitCount]))
                    {
                        ++digitCount;
                    }

                    var startDigit = 0;
                    if (digitCount > 0)
                    {
                        digitCount = Math.Min(6, digitCount);
                        var prevName = name;
                        name = name.Remove(name.Length - digitCount);

                        if (!currentCounters.TryGetValue(name, out startDigit))
                        {
                            startDigit = int.Parse(prevName.Substring(prevName.Length - digitCount, digitCount));
                        }
                    }

                    string newName;
                    do
                    {
                        newName = name + startDigit;
                        ++startDigit;
                    } while (duplicates.Contains(newName) || currentNames.Contains(newName) || !validatorFunc(newName));

                    nameSetter(groupItem, newName);
                    currentNames.Add(newName);

                    currentCounters.Remove(name);
                    currentCounters.Add(name, startDigit);
                }
            }
        }
コード例 #24
0
        public static void MakeUniqueNames <T>(
            IEnumerable <T> items,
            ISet <string>?namesParameter,
            Func <string, ISet <string>?, bool> validatorFunc,
            Func <T, string?> nameFunc,
            Action <T, string, ISet <string>?> nameSetter,
            Func <T, string?> defaultName,
            StringComparer?comparer = null)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }
            if (validatorFunc == null)
            {
                throw new ArgumentNullException(nameof(validatorFunc));
            }
            if (nameFunc == null)
            {
                throw new ArgumentNullException(nameof(nameFunc));
            }
            if (nameSetter == null)
            {
                throw new ArgumentNullException(nameof(nameSetter));
            }
            if (defaultName == null)
            {
                throw new ArgumentNullException(nameof(defaultName));
            }

            HashSet <string>?        currentNames    = null;
            Dictionary <string, int>?currentCounters = null;

            foreach (var item in items)
            {
                var name = nameFunc(item);
                if (!name.IsNullOrEmpty() && currentNames?.Contains(name) != true && validatorFunc(name, namesParameter))
                {
                    if (currentNames == null)
                    {
                        currentNames = new HashSet <string>(comparer);
                    }
                    currentNames.Add(name);
                    nameSetter(item, name, namesParameter);
                    continue;
                }

                if (currentNames == null)
                {
                    currentNames = new HashSet <string>(comparer);
                }
                if (currentCounters == null)
                {
                    currentCounters = new Dictionary <string, int>(comparer);
                }

                name = defaultName(item);

                if (name.IsNullOrEmpty())
                {
                    name = nameFunc(item);
                }
                if (name.IsNullOrEmpty())
                {
                    name = "t";
                }

                var digitCount = 0;
                while (char.IsDigit(name[name.Length - 1 - digitCount]))
                {
                    ++digitCount;
                }

                var startDigit = 0;
                if (digitCount > 0)
                {
                    digitCount = Math.Min(6, digitCount);
                    var prevName = name;
                    name = name.Remove(name.Length - digitCount);

                    if (!currentCounters.TryGetValue(name, out startDigit))
                    {
                        startDigit = int.Parse(prevName.Substring(prevName.Length - digitCount, digitCount));
                    }
                }

                string newName;
                do
                {
                    newName = name + startDigit;
                    ++startDigit;
                } while (currentNames.Contains(newName) || !validatorFunc(newName, namesParameter));

                nameSetter(item, newName, namesParameter);
                currentNames.Add(newName);

                currentCounters.Remove(name);
                currentCounters.Add(name, startDigit);
            }
        }
コード例 #25
0
        internal static IReadOnlyDictionary <string, IReadOnlyList <string> > ToStringListDictionary(this JToken token, StringComparer?comparer = null, string?propertyName = null)
        {
            Dictionary <string, IReadOnlyList <string> > result = new Dictionary <string, IReadOnlyList <string> >(comparer ?? StringComparer.Ordinal);

            foreach (JProperty property in token.PropertiesOf(propertyName))
            {
                if (property.Value == null)
                {
                    continue;
                }
                else if (property.Value.Type == JTokenType.String)
                {
                    result[property.Name] = new List <string>()
                    {
                        property.Value.ToString()
                    };
                }
                else if (property.Value.Type == JTokenType.Array)
                {
                    result[property.Name] = property.Value.ArrayAsStrings();
                }
            }

            return(result);
        }