将索引号追加到列表中的重复字符串值 - 通过使用 Lambda
本文关键字:字符串 Lambda 追加 索引 列表 | 更新日期: 2023-09-27 18:36:20
我有一个包含一些字符串值的IList<string>()
,列表中可能有重复的项目。我想要的是将索引号附加到字符串的末尾以消除重复。
例如,我的列表中有这些值:StringA,StringB,StringC,StringA,StringA,StringB。我希望结果看起来像:StringA1,StringB1,StringC,StringA2,StringA3,StringB2。我需要保留列表中的原始顺序。
有没有办法只使用一个 Lambda 表达式?
您正在寻找类似这样的东西:
yourList.GroupBy(x => x)
.SelectMany(g => g.Select((x,idx) => g.Count() == 1 ? x : x + idx))
.ToList();
编辑:如果元素顺序很重要,这是另一种解决方案:
var counts = yourList.GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count());
var values = counts.ToDictionary(x => x.Key, x => 0);
var list = yourList.Select(x => counts[x] > 1 ? x + ++values[x] : x).ToList();
你可以做:
List<string> list = new List<string> { "StringA", "StringB", "StringC", "StringA", "StringA", "StringB" };
var newList =
list.Select((r, i) => new { Value = r, Index = i })
.GroupBy(r => r.Value)
.Select(grp => grp.Count() > 1 ?
grp.Select((subItem, i) => new
{
Value = subItem.Value + (i + 1),
OriginalIndex = subItem.Index
})
: grp.Select(subItem => new
{
Value = subItem.Value,
OriginalIndex = subItem.Index
}))
.SelectMany(r => r)
.OrderBy(r => r.OriginalIndex)
.Select(r => r.Value)
.ToList();
您将获得:
StringA1,StringB1,StringC,StringA2,StringA3,StringB2
如果你不想保持秩序,那么你可以这样做:
var newList = list.GroupBy(r => r)
.Select(grp => grp.Count() > 1 ?
grp.Select((subItem, i) => subItem + (i + 1))
: grp.Select(subItem => subItem))
.SelectMany(r => r)
.ToList();
这使用了一些 lambda 表达式和 linq 来做到这一点,保持顺序,但我建议使用带有 foreach
循环的函数,yield return
会更好。
var result = list.Aggregate(
new List<KeyValuePair<string, int>>(),
(cache, s) =>
{
var last = cache.Reverse().FirstOrDefault(p => p.Key == s);
if (last == null)
{
cache.Add(new KeyValuePair<string, int>(s, 0));
}
else
{
if (last.Value = 0)
{
last.Value = 1;
}
cache.Add(new KeyValuePair<string, int>(s, last.Value + 1));
}
return cache;
},
cache => cache.Select(p => p.Value == 0 ?
p.Key :
p.Key + p.Value.ToString()));