Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用LINQ重命名列表中的重复项_C#_Linq - Fatal编程技术网

C# 如何使用LINQ重命名列表中的重复项

C# 如何使用LINQ重命名列表中的重复项,c#,linq,C#,Linq,我需要一个唯一值的列表。但也可能是,这些值在列表中存在两次或两次以上。 如果发生这种情况,我必须重命名该值,但重命名后的值也可能在列表中 可以使用LINQ查询重命名这些值,这样我就不需要子查询了 例1: 之前: “一”、“一”、“二”、“二”、“三” 之后: “一”、“一”、“二”、“二”、“三” 例2: 之前: “一”、“一”、“一” 之后: “一”、“一”、“一” 第三个“一”有2个下划线,因为第二个“一”已重命名为“一” 非常感谢您的建议……我认为这不应该仅仅通过linq查询来完成。如果我

我需要一个唯一值的列表。但也可能是,这些值在列表中存在两次或两次以上。 如果发生这种情况,我必须重命名该值,但重命名后的值也可能在列表中

可以使用LINQ查询重命名这些值,这样我就不需要子查询了

例1: 之前: “一”、“一”、“二”、“二”、“三” 之后: “一”、“一”、“二”、“二”、“三”

例2: 之前: “一”、“一”、“一” 之后: “一”、“一”、“一”

第三个“一”有2个下划线,因为第二个“一”已重命名为“一”


非常感谢您的建议……

我认为这不应该仅仅通过linq查询来完成。如果我是你,我会使用哈希集并创建一个函数。大概是这样的:

IEnumerable<String> GetUnique(IEnumerable<String> list) {
    HashSet<String> itms = new HashSet<String>();
    foreach(string itm in list) {
         string itr = itm;
         while(itms.Contains(itr)) {
             itr = itr + "_";
         }
         itms.Add(itr);
         yield return itr;
    }
}
public static IEnumerable<string> Uniquifier(this IEnumerable<string> values)
{
    if (values == null) throw new ArgumentNullException("values");

    var unique = new HashSet<string>();

    foreach(var item in values)
    {
        var newItem = item;

        while(unique.Contains(newItem))
        {
            newItem += '_';
        }

        unique.Add(newItem);

        yield return newItem;
    }
}
IEnumerable GetUnique(IEnumerable列表){
HashSet itms=新HashSet();
foreach(列表中的字符串itm){
字符串itr=itm;
而(itms.Contains(itr)){
itr=itr+“u2;”;
}
itms.Add(itr);
收益率;
}
}
[编辑] 不过,这可以被做成一个扩展方法,所以您可以这样调用它:
myList.GetUnique()(或类似的东西)

[编辑2]
修复了迭代器变量被更改的错误。

我将创建一个新的扩展方法,如下所示:

IEnumerable<String> GetUnique(IEnumerable<String> list) {
    HashSet<String> itms = new HashSet<String>();
    foreach(string itm in list) {
         string itr = itm;
         while(itms.Contains(itr)) {
             itr = itr + "_";
         }
         itms.Add(itr);
         yield return itr;
    }
}
public static IEnumerable<string> Uniquifier(this IEnumerable<string> values)
{
    if (values == null) throw new ArgumentNullException("values");

    var unique = new HashSet<string>();

    foreach(var item in values)
    {
        var newItem = item;

        while(unique.Contains(newItem))
        {
            newItem += '_';
        }

        unique.Add(newItem);

        yield return newItem;
    }
}
公共静态IEnumerable Uniquifier(此IEnumerable值)
{
如果(value==null)抛出新的ArgumentNullException(“值”);
var unique=新的HashSet();
foreach(值中的var项)
{
var newItem=项目;
while(unique.Contains(newItem))
{
newItem+='389;';
}
唯一。添加(newItem);
收益返回新项目;
}
}

这将获取任何字符串序列,并创建一个值的哈希集(非常快,O(1))。如果该值已存在,则会附加一个“389;”并重试。一旦它有一个唯一的,就返回它。

使用扩展方法:

public static class EnumerableExtensions
{
    public static IEnumerable<string> Uniquify(this IEnumerable<string> enumerable, string suffix)
    {
        HashSet<string> prevItems = new HashSet<string>();
        foreach(var item in enumerable)
        {
            var temp = item;
            while(prevItems.Contains(temp))
            {
                temp += suffix;
            }
            prevItems.Add(temp);
            yield return temp;
        }
    }
}
实例:


编辑:根据下面的评论,使用while循环现在支持以前不支持的所有情况。

即将发布类似的内容!我唯一的建议是将它作为一个扩展方法,这样调用起来更容易一些,并且在构建要插入的候选字符串时使用
StringBuilder
,以避免大量低效的字符串连接。@Alxandr:Darn,这是我两次在键入我自己的答案时被击败:-)我曾想过使用StringBuilder,但后来我想,通常情况下,您可能只会使用在末尾添加1或2“u”的列表;在这种情况下,我认为使用StringBuilder的收益超过了在while循环中调用ToString的成本。。。嗯,我只是觉得这不值得。@Alxandr:同意,因为每次查找都需要字符串,concat(+)更有效。@StriplingWarrior:等等,什么?你的意思是如果我做了
string a=“a”;字符串b=“b”;字符串c=a+bC#(幕后)创建用于连接的StringBuilder?这不是浪费了内存吗?LINQ不适合修改集合,但适合查询集合。我同意Alxandr的建议。@Jens:这并不要求修改TSource,只要求查询派生项。但是同意这个建议。你应该用哈希集来切换列表。速度快得多,算法错误。如果同一字符串值出现多次,则使用
“一”、“一”、“一”
进行测试不起作用。这是实际编译并正确工作的第一个答案。