我有一个收藏品。在此集合中,如果添加了副本,我想附加文本“ - N”(其中N是集合中当前项目未使用的整数)。
例如,如果我有以下列表:
并尝试再次添加'item1',我希望列表最终如此:
如果我再次尝试添加“item1”,则列表将为:
非常直接。下面是我的简单算法,但在处理10,000个项目时,我的性能明显下降。显然这会发生一些,但有更好的方法吗?找不到任何类似的问题,所以我想看看是否有人遇到过类似的问题。
Item copyItem = new Item();
string tempName = name;
int copyNumber = 1;
while(copyItem != null)
{
copyItem = MyCollection.FirstOrDefault(blah => blah.Name == tempName);
if (copyItem == null)
{
name = tempName;
break;
}
tempName = name + " - " + copyNumber;
++copyNumber;
}
答案 0 :(得分:2)
我首先要对值进行排序 - 多亏了这一点,你只需要检查前一个值而不是整个集合。
所以看起来像这样:
List<string> values = new List<string> { "item1", "item1", "item1" };
values.Sort();
string previousValue = string.Empty;
int number = 1;
for(int i = 0 ; i < values.Count; i ++)
{
if (values[i].Equals(previousValue))
{
previousValue = values[i];
values[i] = values[i] + "-" + number;
number++;
}
else
{
previousValue = values[i];
number = 1;
}
}
答案 1 :(得分:2)
我会使用Dictionary<string, int>
来存储特定项目的重复项数量。因此,辅助方法看起来像这样:
Dictionary<string, int> countDictionary = new Dictionary<string, int>(); // case sensitive!
string GetNameForItem(string itemName)
{
var name = itemName;
var count = 0;
countDictionary.TryGetValue(itemName, out count);
if (count > 0)
name = string.Format("{0} - {1}", itemName, count);
countDictionary[itemName] = count + 1;
return name;
}
或者,如果您不希望GetNameForItem
在检索时自动递增,则可以将操作拆分为多个方法:
int GetCountForItem(string itemName)
{
var count = 0;
countDictionary.TryGetValue(itemName, out count);
return count;
}
string GetNameForItem(string itemName)
{
var name = itemName;
var count = GetCountForItem(itemName);
if (count > 0)
name = string.Format("{0} - {1}", itemName, count);
return name;
}
int IncrementCountForItem(string itemName)
{
var newCount = GetCountForItem(itemName) + 1;
countDictionary[itemName] = newCount;
return newCount;
}
重要的是要注意,如果您支持从集合中删除,则必须相应地更新计数:
int DecrementCountForItem(string itemName)
{
var newCount = Math.Max(0, GetCountForItem(itemName) - 1); // Prevent count from going negative!
countDictionary[itemName] = newCount;
return newCount;
}
如果您有两个项目,例如“项目A ”和“项目A - 1 ”,您还必须记住会发生什么,然后删除“ 项目A “。您是否应该将“项目A - 1 ”重命名为“项目A ”?
答案 2 :(得分:0)
好吧所以你需要一个每个值的迭代器而不是一个全局迭代器。这段代码可以做到这一点。
// Inputs for Tests purpose
List<string> values = new List<string> { "item1", "item2", "item1", "item1" };
// Result data
List<string> finalResult = new List<string>();
// 1 - Group by item value
var tempResult = from i in values
group i by i;
// We loop over all different item name
foreach (var curItem in tempResult)
{
// Thanks to the group by we know how many item with the same name exists
for (int ite = 0; ite < curItem.Count(); ite++)
{
if (ite == 0)
finalResult.Add(curItem.Key);
else
finalResult.Add(string.Format("{0} - {1}", curItem.Key, ite));
}
}
感谢LINQ,您可以减少代码量,下一代码将执行完全相同的操作,并且应该更快,因为我使用ToList()方法,因此LINQ查询将不会有延迟执行。
// Inputs for Tests purpose
List<string> values = new List<string> { "item1", "item2", "item1", "item1" };
// Result data
List<string> finalResult = new List<string>();
values.GroupBy<string, string>(s1 => s1).ToList().ForEach(curItem =>
{
for (int ite = 0; ite < curItem.Count(); ite++)
{
finalResult.Add(ite == 0 ? curItem.Key : string.Format("{0} - {1}", curItem.Key, ite));
}
});