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