예제 #1
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 随机打乱字符串中的所有字符
        /// </summary>
        /// <param name="str">需要被打乱的字符串</param>
        /// <param name="seed">种子</param>
        /// <returns>被打乱的字符串</returns>
        public static string Shuffle(string str, int?seed = null)
        {
            KGuard.Requires <ArgumentNullException>(str != null);
            var random = KUtil.MakeRandom(seed);

            var requested = new string[str.Length];

            for (var i = 0; i < str.Length; i++)
            {
                var index = random.Next(0, str.Length - 1);

                requested[i]     = requested[i] ?? str.Substring(i, 1);
                requested[index] = requested[index] ?? str.Substring(index, 1);

                if (index == i)
                {
                    continue;
                }

                var temp = requested[i];
                requested[i]     = requested[index];
                requested[index] = temp;
            }

            return(KArray.Reduce(requested, (v1, v2) => v1 + v2, string.Empty));
        }
예제 #2
0
        /// <summary>
        /// 将一个或多个元素加入数组尾端
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="elements">要加入的元素</param>
        /// <returns>数组的元素个数</returns>
        public static int Push <T>(ref T[] source, params T[] elements)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            KGuard.Requires <InvalidOperationException>(elements != null);

            Array.Resize(ref source, source.Length + elements.Length);
            Array.Copy(elements, 0, source, source.Length - elements.Length, elements.Length);

            return(source.Length);
        }
예제 #3
0
        /// <summary>
        /// 删除数组中的最后一个元素,并将删除的元素作为返回值返回
        /// </summary>
        /// <typeparam name="T">删除数组中的最后一个元素</typeparam>
        /// <param name="source">规定数组</param>
        /// <returns>被删除的元素</returns>
        public static T Pop <T>(ref T[] source)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            KGuard.Requires <InvalidOperationException>(source.Length > 0);

            T result = source[source.Length - 1];

            Array.Resize(ref source, source.Length - 1);
            return(result);
        }
예제 #4
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 替换规定字符串中从后往前第一次遇到的匹配项
        /// <para>该函数对大小写敏感</para>
        /// </summary>
        /// <param name="match">匹配项</param>
        /// <param name="replace">替换的内容</param>
        /// <param name="str">规定字符串</param>
        /// <returns>替换后的字符串</returns>
        public static string ReplaceLast(string match, string replace, string str)
        {
            KGuard.Requires <ArgumentNullException>(match != null);
            KGuard.Requires <ArgumentNullException>(replace != null);
            KGuard.Requires <ArgumentNullException>(str != null);

            var index = str.LastIndexOf(match, StringComparison.Ordinal);

            return(index < 0 ? str : str.Remove(index, match.Length).Insert(index, replace));
        }
예제 #5
0
        /// <summary>
        /// 在数组中根据条件取出一段值,并返回。
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="start">
        /// 取出元素的开始位置。
        /// <para>如果该值设置为正数,则从前往后开始取</para>
        /// <para>如果该值设置为负数,则从后向前取 <paramref name="start"/> 绝对值。-2 意味着从数组的倒数第二个元素开始</para>
        /// </param>
        /// <param name="length">
        /// 被返回数组的长度
        /// <para>如果该值设置为整数,则返回该数量的元素。</para>
        /// <para>如果该值设置为负数,则则从后向前取 <paramref name="length"/> 绝对值位置终止取出。-1 意味着从数组的倒数第一个元素前终止</para>
        /// <para>如果该值未设置,则返回从 <paramref name="start"/> 参数设置的位置开始直到数组末端的所有元素。</para>
        /// </param>
        /// <returns>取出的数组</returns>
        public static T[] Slice <T>(T[] source, int start, int?length = null)
        {
            KGuard.Requires <ArgumentNullException>(source != null);

            KUtil.NormalizationPosition(source.Length, ref start, ref length);

            var requested = new T[length.Value];

            Array.Copy(source, start, requested, 0, length.Value);

            return(requested);
        }
예제 #6
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 在规定字符串中替换匹配项
        /// </summary>
        /// <param name="matches">匹配项</param>
        /// <param name="replace">替换的值</param>
        /// <param name="str">规定字符串</param>
        /// <returns></returns>
        public static string Replace(string[] matches, string replace, string str)
        {
            KGuard.Requires <ArgumentNullException>(matches != null);
            KGuard.Requires <ArgumentNullException>(replace != null);
            KGuard.Requires <ArgumentNullException>(str != null);

            foreach (var match in matches)
            {
                str = str.Replace(match, replace);
            }
            return(str);
        }
예제 #7
0
        /// <summary>
        /// 删除数组中第一个元素,并返回被删除元素的值
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <returns>被删除元素的值</returns>
        public static T Shift <T>(ref T[] source)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            KGuard.Requires <InvalidOperationException>(source.Length > 0);

            var requested = source[0];
            var newSource = new T[source.Length - 1];

            Array.Copy(source, 1, newSource, 0, source.Length - 1);
            source = newSource;

            return(requested);
        }
예제 #8
0
        /// <summary>
        /// 向用户自定义函数发送数组中的值,并返回一个字符串
        /// <para>如果数组是空的且未传递<paramref name="initial"/>参数,该函数返回 null</para>
        /// <para>如果指定了<paramref name="initial"/>参数,则该参数将被当成是数组中的第一个值来处理,如果数组为空的话就作为最终返回值(string)</para>
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="callback">自定义函数</param>
        /// <param name="initial">初始值</param>
        /// <returns></returns>
        public static string Reduce <T>(T[] source, Func <object, T, string> callback, object initial = null)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            KGuard.Requires <ArgumentNullException>(callback != null);

            var requested = initial;

            foreach (var segments in source)
            {
                requested = callback.Invoke(requested, segments);
            }
            return(requested == null ? null : requested.ToString());
        }
예제 #9
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 根据长度将字符串分割到数组中
        /// </summary>
        /// <param name="str">要分割的字符串</param>
        /// <param name="length">规定每个数组元素的长度。默认是 1。</param>
        /// <returns>分割的字符串</returns>
        public static string[] Split(string str, int length = 1)
        {
            KGuard.Requires <ArgumentNullException>(str != null);
            KGuard.Requires <ArgumentOutOfRangeException>(length > 0);
            var requested = new string[str.Length / length + (str.Length % length == 0 ? 0 : 1)];

            for (var i = 0; i < str.Length; i += length)
            {
                requested[i / length] = str.Substring(i, Math.Min(str.Length - i, length));
            }

            return(requested);
        }
예제 #10
0
        /// <summary>
        /// 向数组插入新元素。新数组的值将被插入到数组的开头。
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="elements">插入的元素</param>
        /// <returns>数组元素个数</returns>
        public static int Unshift <T>(ref T[] source, params T[] elements)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            KGuard.Requires <ArgumentNullException>(elements != null);

            var newSource = new T[source.Length + elements.Length];

            Array.Copy(elements, newSource, elements.Length);
            Array.Copy(source, 0, newSource, elements.Length, source.Length);

            source = newSource;

            return(source.Length);
        }
예제 #11
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 判断规定字符串是否包含规定子字符串
        /// <para>子字符串是识别大小写的</para>
        /// <para></para>
        /// </summary>
        /// <param name="str">规定字符串</param>
        /// <param name="needles">规定子字符串</param>
        /// <returns>是否包含</returns>
        public static bool Contains(string str, params string[] needles)
        {
            KGuard.Requires <ArgumentNullException>(str != null);
            KGuard.Requires <ArgumentNullException>(needles != null);

            foreach (var needle in needles)
            {
                if (str.Contains(needle))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #12
0
        /// <summary>
        /// 将数组值传入用户自定义函数,自定义函数返回的值作为新的数组值
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="callback">自定义函数</param>
        /// <returns>处理后的数组</returns>
        public static T[] Map <T>(T[] source, Func <T, T> callback)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            KGuard.Requires <ArgumentNullException>(callback != null);

            var requested = new T[source.Length];

            Array.Copy(source, requested, source.Length);

            for (var i = 0; i < source.Length; i++)
            {
                requested[i] = callback.Invoke(source[i]);
            }

            return(requested);
        }
예제 #13
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 在规定字符串中查找在规定搜索值,并在规定搜索值之后返回规定字符串的剩余部分。
        /// <para>如果没有找到则返回规定字符串本身</para>
        /// </summary>
        /// <param name="str">规定字符串</param>
        /// <param name="search">规定搜索值</param>
        /// <returns>剩余部分</returns>
        public static string After(string str, string search)
        {
            KGuard.Requires <ArgumentNullException>(search != null);
            if (str == null || str.Length <= 0)
            {
                return(str);
            }

            var index = str.IndexOf(search);

            if (index < 0)
            {
                return(str);
            }

            return(str.Substring(index + search.Length, str.Length - index - search.Length));
        }
예제 #14
0
        /// <summary>
        /// 从数组中移除指定长度的元素,如果给定了<paramref name="replSource"/>参数,那么新元素从<paramref name="start"/>位置开始插入
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="start">
        /// 删除元素的开始位置。
        /// <para>如果该值设置为正数,则从前往后开始删除</para>
        /// <para>如果该值设置为负数,则从后向前取 <paramref name="start"/> 绝对值。-2 意味着从数组的倒数第二个元素开始</para></param>
        /// <param name="length">
        /// 删除元素的个数,也是被返回数组的长度
        /// <para>如果该值设置为整数,则返回该数量的元素。</para>
        /// <para>如果该值设置为负数,则则从后向前取 <paramref name="length"/> 绝对值位置终止删除。-1 意味着从数组的倒数第一个元素前删除</para>
        /// <para>如果该值未设置,则返回从 <paramref name="start"/> 参数设置的位置开始直到数组末端的所有元素。</para>
        /// </param>
        /// <param name="replSource">在start位置插入的数组</param>
        /// <returns>被删除的数组</returns>
        public static T[] Splice <T>(ref T[] source, int start, int?length = null, T[] replSource = null)
        {
            KGuard.Requires <ArgumentNullException>(source != null);

            KUtil.NormalizationPosition(source.Length, ref start, ref length);

            var requested = new T[length.Value];

            if (length.Value == source.Length)
            {
                // 现在移除所有旧的元素,然后用新的元素替换。
                Array.Copy(source, requested, source.Length);
                source = replSource ?? new T[] { };
                return(requested);
            }

            Array.Copy(source, start, requested, 0, length.Value);

            if (replSource == null || replSource.Length == 0)
            {
                var newSource = new T[source.Length - length.Value];
                // 现在只删除不插入
                if (start > 0)
                {
                    Array.Copy(source, 0, newSource, 0, start);
                }
                Array.Copy(source, start + length.Value, newSource, start, source.Length - (start + length.Value));
                source = newSource;
            }
            else
            {
                var newSource = new T[source.Length - length.Value + replSource.Length];
                // 删除并且插入
                if (start > 0)
                {
                    Array.Copy(source, 0, newSource, 0, start);
                }
                Array.Copy(replSource, 0, newSource, start, replSource.Length);
                Array.Copy(source, start + length.Value, newSource, start + replSource.Length,
                           source.Length - (start + length.Value));
                source = newSource;
            }

            return(requested);
        }
예제 #15
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 将字符串重复指定的次数
        /// </summary>
        /// <param name="str">需要被重复的字符串</param>
        /// <param name="num">重复的次数</param>
        /// <returns>重复后的字符串</returns>
        public static string Repeat(string str, int num)
        {
            KGuard.Requires <ArgumentNullException>(str != null);
            KGuard.Requires <ArgumentOutOfRangeException>(num >= 0);

            if (num == 0)
            {
                return(str);
            }

            var requested = new StringBuilder();

            for (var i = 0; i < num; i++)
            {
                requested.Append(str);
            }
            return(requested.ToString());
        }
예제 #16
0
        /// <summary>
        /// 从规定数组中获取一个或者指定数量的随机值
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="number">随机的数量</param>
        /// <returns>随机后的元素</returns>
        public static T[] Rand <T>(T[] source, int number = 1)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            number = Math.Max(number, 1);
            source = Shuffle(source);
            var requested = new T[number];
            var i         = 0;

            foreach (var result in source)
            {
                if (i >= number)
                {
                    break;
                }
                requested[i++] = result;
            }

            return(requested);
        }
예제 #17
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 生成一个随机字母(含大小写),数字的字符串。
        /// </summary>
        /// <param name="length">字符串长度</param>
        /// <param name="seed">种子</param>
        /// <returns>随机的字符串</returns>
        public static string Random(int length = 16, int?seed = null)
        {
            KGuard.Requires <ArgumentOutOfRangeException>(length > 0);

            var requested = string.Empty;
            var random    = KUtil.MakeRandom(seed);

            for (int len; (len = requested.Length) < length;)
            {
                var size  = length - len;
                var bytes = new byte[size];
                random.NextBytes(bytes);

                var code = Replace(new[] { "/", "+", "=" }, string.Empty, Convert.ToBase64String(bytes));
                requested += code.Substring(0, Math.Min(size, code.Length));
            }

            return(requested);
        }
예제 #18
0
        /// <summary>
        /// 输入数组中的每个值传给回调函数,如果回调函数返回 true,则把输入数组中的当前值加入结果数组中
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="predicate">回调函数</param>
        /// <returns>需求数组</returns>
        public static T[] Filter <T>(T[] source, Predicate <T> predicate)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            KGuard.Requires <ArgumentNullException>(predicate != null);
            var elements = new T[source.Length];

            var i = 0;

            foreach (var result in source)
            {
                if (predicate.Invoke(result))
                {
                    elements[i++] = result;
                }
            }

            Array.Resize(ref elements, i);
            return(elements);
        }
예제 #19
0
        /// <summary>
        /// 将多个规定数组合并成一个数组
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="sources">规定数组</param>
        /// <returns>合并后的数组</returns>
        public static T[] Merge <T>(params T[][] sources)
        {
            KGuard.Requires <ArgumentNullException>(sources != null);
            var length = 0;

            foreach (var source in sources)
            {
                length += source.Length;
            }

            var merge   = new T[length];
            var current = 0;

            foreach (var source in sources)
            {
                Array.Copy(source, 0, merge, current, source.Length);
                current += source.Length;
            }

            return(merge);
        }
예제 #20
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 计算子串在字符串中出现的次数
        /// <para>该函数不计数重叠的子串</para>
        /// </summary>
        /// <param name="str">规定字符串</param>
        /// <param name="subStr">子字符串</param>
        /// <param name="start">起始位置</param>
        /// <param name="length">需要扫描的长度</param>
        /// <param name="comparison">扫描规则</param>
        /// <returns>子字符串出现的次数</returns>
        public static int SubstringCount(string str, string subStr, int start = 0, int?length = null, StringComparison comparison = StringComparison.CurrentCultureIgnoreCase)
        {
            KGuard.Requires <ArgumentNullException>(str != null);
            KGuard.Requires <ArgumentNullException>(subStr != null);

            KUtil.NormalizationPosition(str.Length, ref start, ref length);

            var count = 0;

            while (length.Value > 0)
            {
                int index;
                if ((index = str.IndexOf(subStr, start, length.Value, comparison)) < 0)
                {
                    break;
                }
                count++;
                length -= index + subStr.Length - start;
                start   = index + subStr.Length;
            }

            return(count);
        }
예제 #21
0
        /// <summary>
        /// 将规定数组中的元素打乱
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="seed">种子</param>
        /// <returns>打乱后的数组</returns>
        public static T[] Shuffle <T>(T[] source, int?seed = null)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            var requested = new T[source.Length];

            Array.Copy(source, requested, source.Length);

            var random = KUtil.MakeRandom(seed);

            for (var i = 0; i < requested.Length; i++)
            {
                var index = random.Next(0, requested.Length - 1);
                if (index == i)
                {
                    continue;
                }
                var temp = requested[i];
                requested[i]     = requested[index];
                requested[index] = temp;
            }

            return(requested);
        }
예제 #22
0
파일: KString.cs 프로젝트: qipa/KXFramework
        /// <summary>
        /// 把字符串填充为新的长度。
        /// </summary>
        /// <param name="str">规定要填充的字符串</param>
        /// <param name="length">规定新的字符串长度。如果该值小于字符串的原始长度,则不进行任何操作。</param>
        /// <param name="padStr">
        /// 规定供填充使用的字符串。默认是空白。
        /// <para>如果传入的字符串长度小于等于0那么会使用空白代替。</para>
        /// <para>注释:空白不是空字符串</para>
        /// </param>
        /// <param name="type">
        /// 规定填充字符串的哪边。
        /// <para><see cref="PadTypes.Both"/>填充字符串的两侧。如果不是偶数,则右侧获得额外的填充。</para>
        /// <para><see cref="PadTypes.Left"/>填充字符串的左侧。</para>
        /// <para><see cref="PadTypes.Right"/>填充字符串的右侧。默认。</para>
        /// </param>
        /// <returns>被填充的字符串</returns>
        public static string Pad(string str, int length, string padStr = null, PadTypes type = PadTypes.Right)
        {
            KGuard.Requires <ArgumentNullException>(str != null);

            var needPadding = length - str.Length;

            if (needPadding <= 0)
            {
                return(str);
            }

            int rightPadding;
            var leftPadding = rightPadding = 0;

            if (type == PadTypes.Both)
            {
                leftPadding  = needPadding >> 1;
                rightPadding = (needPadding >> 1) + (needPadding % 2 == 0 ? 0 : 1);
            }
            else if (type == PadTypes.Right)
            {
                rightPadding = needPadding;
            }
            else
            {
                leftPadding = needPadding;
            }

            padStr = padStr ?? " ";
            padStr = padStr.Length <= 0 ? " " : padStr;

            var leftPadCount  = leftPadding / padStr.Length + (leftPadding % padStr.Length == 0 ? 0 : 1);
            var rightPadCount = rightPadding / padStr.Length + (rightPadding % padStr.Length == 0 ? 0 : 1);

            return(Repeat(padStr, leftPadCount).Substring(0, leftPadding) + str +
                   Repeat(padStr, rightPadCount).Substring(0, rightPadding));
        }
예제 #23
0
        /// <summary>
        /// 对数组进行填充,如果传入了规定数组,那么会在规定数组的基础上进行填充
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="start">起始下标</param>
        /// <param name="length">填充长度</param>
        /// <param name="value">填充的值</param>
        /// <param name="source">规定数组</param>
        /// <returns>填充后的数组</returns>
        public static T[] Fill <T>(int start, int length, T value, T[] source = null)
        {
            KGuard.Requires <ArgumentOutOfRangeException>(start >= 0);
            KGuard.Requires <ArgumentOutOfRangeException>(length > 0);
            var count     = start + length;
            var requested = new T[source == null ? count : source.Length + count];

            if (start > 0 && source != null)
            {
                Array.Copy(source, requested, Math.Min(source.Length, start));
            }

            for (var i = start; i < count; i++)
            {
                requested[i] = value;
            }

            if (source != null && start < source.Length)
            {
                Array.Copy(source, start, requested, count, source.Length - start);
            }

            return(requested);
        }
예제 #24
0
        /// <summary>
        /// 将数组分为新的数组块
        /// <para>其中每个数组的单元数目由 <paramref name="size"/> 参数决定。最后一个数组的单元数目可能会少几个。</para>
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="source">规定数组</param>
        /// <param name="size">每个分块的大小</param>
        /// <returns></returns>
        public static T[][] Chunk <T>(T[] source, int size)
        {
            KGuard.Requires <ArgumentNullException>(source != null);
            size = Math.Max(1, size);
            var requested = new T[source.Length / size + (source.Length % size == 0 ? 0 : 1)][];

            T[] chunk = null;
            for (var i = 0; i < source.Length; i++)
            {
                var pos = i / size;
                if (i % size == 0)
                {
                    if (chunk != null)
                    {
                        requested[pos - 1] = chunk;
                    }
                    chunk = new T[(i + size) <= source.Length ? size : source.Length - i];
                }
                chunk[i - (pos * size)] = source[i];
            }
            requested[requested.Length - 1] = chunk;

            return(requested);
        }