【问题标题】:How to efficiently duplicate a specific value in a list如何有效地复制列表中的特定值
【发布时间】:2021-01-09 15:20:47
【问题描述】:

在 C# 中,如何复制列表中的值? 我已经找到了大量关于如何删除的智能解决方案(尤其是在 Linq 中),但没有一个关于如何复制的解决方案,而且无论如何都无法根据我的需要调整代码。

例如如果我想复制 16 --> Lst {0 0 12 13 16 0 3} ---> {0 0 12 13 16 16 0 3}

我不必循环使用它们,但更喜欢单个指令

感谢您的帮助

帕特里克

【问题讨论】:

  • 如果多次出现怎么办?全部复制?还是“我不必骑自行车”仅意味着第一个?您想要对列表进行就地修改,还是想要获得一个包含重复项目的新列表?

标签: c# arrays list linq


【解决方案1】:

您可以编写自己的扩展方法,使用方式与默认 LINQ 方法相同:

public static IEnumerable<T> Duplicate<T>(this IEnumerable<T> input, T toDuplicate)
{
    foreach(T item in input)
    {
        yield return item;
        if(EqualityComparer<T>.Default.Equals(item, toDuplicate))
        {
            yield return item;
        }
    }
}

用法是

var test = new List<int>() { 0, 0, 12, 13, 16, 0, 3 };
var duplicated = test.Duplicate(16).ToList();

【讨论】:

  • 您可以通过使用object.Equals() 而不是== 使其通用,但要注意空值!
  • 为了使其通用,您可以使用 T 类型的 default comparerEqualityComparer&lt;T&gt;.Default.Equals(item, toDuplicate)
  • @Matthew Watson:感谢您的提示。我已经更新了答案
  • 实际上您应该使用 Theodor 的建议 - 尽管 object.Equals() 可以工作,但您还必须检查空值,您当前的实现不会这样做,如果有任何一个,则会抛出 NullReferenceException项目为空。 EqualityComparer&lt;T&gt;.Equals() 为你做这件事。
【解决方案2】:

试试这个


list.Insert((list.FindIndex(a => a== valueToBeDuplicated) + 1), valueToBeDuplicated));

所以FindIndex(a =&gt; a == valueToBeDuplicated) 将获得索引,然后通过添加+ 1 将其插入到下一个索引中。

【讨论】:

  • 这个有两个问题。如果valueToBeDuplicated 不在列表中,它将在列表的开头插入它。此外,它只会复制该值的第一个实例,而其他答案将复制所有实例(可能需要也可能不需要)。
【解决方案3】:

结合SelectManyRepeat 操作符是一个简单但可能不是最佳的解决方案:

var result = source.SelectMany(x => Enumerable.Repeat(x, x == 16 ? 2 : 1));

【讨论】:

    猜你喜欢
    • 2019-02-18
    • 1970-01-01
    • 2020-02-27
    • 2019-07-30
    • 2020-02-05
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多