向重复字符串添加增量数字
本文关键字:数字 添加 字符串 | 更新日期: 2023-09-27 17:54:44
我在c#工作。Net4使用Visual Studio),我正试图找出一种算法,根据程序中的现有字符串,将增量数字附加到输入的字符串。不太好到处找答案
有一个List<string>
。例如
{"MyItem (2)", "MyItem", "Other thing", "string here", "MyItem (1)"}
假设用户想要添加另一个字符串到这个列表中,并且他们已经选择了"MyItem"作为要添加的字符串。因此给定输入和现有列表,算法将返回"MyItem(3)"作为要添加的新字符串。
它的功能与Windows资源管理器中相同,您可以不断添加新文件夹("新文件夹(1)","新文件夹(2)"等等)
我正在尝试通过列表循环并找出下一个逻辑数字应该是什么,但我被卡住了(代码越来越大)。有人知道一种优雅的方法吗?(我不太擅长Regex,所以也许这就是我错过的)
应该可以:
var list = new List<string>{"MyItem (2)", "MyItem", "Other thing", "string here", "MyItem (1)"} ;
string str = "MyItem";
string newStr = str;
int i = 0;
while(list.Contains(newStr))
{
i++;
newStr = string.Format("{0} ({1})",str,i);
}
// newStr = "MyItem (3)"
获取input
并搜索它,如果它存在于列表中,则获取计数并连接输入字符串和count + 1,否则只需将输入添加到列表中:
var input = Console.ReadLine(); // just for example
if(list.Any(x => x == input))
{
var count = list.Count(x => x == input);
list.Add(string.Format("{0} ({1})", input, count+1);
}
else list.Add(input);
下面是我用来模拟Windows资源管理器行为的一个有用的扩展方法。
我觉得前面的答案太简单,只满足了部分需求,它们也没有以一种您可以轻松重用的方式呈现。
此解决方案基于您首先确定要比较的字符串列表,它们可能来自文件系统或数据库,由您来解析来自业务域的值列表,然后识别重复项并生成唯一值的过程是非常可重复的。
扩展方法:
/// <summary>
/// Generate a uniquely numbered string to insert into this list
/// Uses convention of appending the value with the duplication index number in brackets "~ (#)"
/// </summary>
/// <remarks>This will not actually add this list</remarks>
/// <param name="input">The string to evaluate against this collection</param>
/// <param name="comparer">[Optional] One of the enumeration values that specifies how the strings will be compared, will default to OrdinalIgnoreCase </param>
/// <returns>A numbered variant of the input string that would be unique in the list of current values</returns>
public static string GetUniqueString(this IList<string> currentValues, string input, StringComparison comparison = StringComparison.OrdinalIgnoreCase)
{
// This matches the pattern we are using, i.e. "A String Value (#)"
var regex = new System.Text.RegularExpressions.Regex(@"'(([0-9]+)')$");
// this is the comparison value that we want to increment
string prefix = input.Trim();
string result = input.Trim();
// let it through if there is no current match
if (currentValues.Any(x => x.Equals(input, comparison)))
{
// Identify if the input value has already been incremented (makes this more reusable)
var inputMatch = regex.Match(input);
if (inputMatch.Success)
{
// this is the matched value
var number = inputMatch.Groups[1].Captures[0].Value;
// remove the numbering from the alias to create the prefix
prefix = input.Replace(String.Format("({0})", number), "").Trim();
}
// Now evaluate all the existing items that have the same prefix
// NOTE: you can do this as one line in Linq, this is a bit easier to read
// I'm trimming the list for consistency
var potentialDuplicates = currentValues.Select(x => x.Trim()).Where(x => x.StartsWith(prefix, comparison));
int count = 0;
int maxIndex = 0;
foreach (string item in potentialDuplicates)
{
// Get the index from the current item
var indexMatch = regex.Match(item);
if (indexMatch.Success)
{
var index = int.Parse(indexMatch.Groups[1].Captures[0].Value);
var test = item.Replace(String.Format("({0})", index), "").Trim();
if (test.Equals(prefix, comparison))
{
count++;
maxIndex = Math.Max(maxIndex, index);
}
}
}
int nextIndex = Math.Max(maxIndex, count) + 1;
result = string.Format("{0} ({1})", prefix, nextIndex);
}
return result;
}
实现:
var list = new string [] { "MyItem (2)", "MyItem", "Other thing", "string here", "MyItem (1)" };
string input = Console.ReadLine(); // simplify testing, thanks @selman-genç
var result = list.GetUniqueString(input, StringComparison.OrdinalIgnoreCase);
// Display the result, you can add it to the list or whatever you need to do
Console.WriteLine(result);
<>之前输入|结果---------------------------------MyItem | MyItem (3)Myitem (1) | Myitem (3)MyItem (3) | MyItem (3)MyItem (4) | MyItem (4)MyItem 4 | MyItem 4String Here | String Here (1)新值|新值 伪代码:如果列表中没有这样的字符串,将其添加到列表中。否则,设置变量N = 1。扫描列表并查找像给定字符串+ "(*)"这样的字符串(这里Regex会有所帮助)。如果找到任何字符串,则从大括号中取出数字并将其与N进行比较。Set N = MAX(该数字+ 1,N)。扫描列表后,N包含要添加的数字。因此,将字符串+ " (N)"添加到列表中