简体   繁体   English

是否有与uniq命令uniq等效的Linq

[英]Is there a Linq equivalent to the unix command uniq

Every search I make assumes "Distinct()", but this is NOT my requirement. 我进行的每一次搜索都假设“ Distinct()”,但这不是我的要求。 I just wish to remove all the repeats. 我只希望删除所有重复项。 Are there any options using linq (ie the Enumerable extensions) ? 是否有使用linq的选项(即Enumerable扩展名)?

For example (in C#) 例如(在C#中)

int[] input = new [] {1,2,3,3,4,5,5,5,6,6,5,4,4,3,2,1,6};

int[] expected = new [] {1,2,3,4,5,6,5,4,3,2,1,6};

It is possible with linq, although for performance and readability a simple for loop would probably be the better option. linq可以实现,尽管对于性能和可读性而言,简单的for循环可能是更好的选择。

int[] input = new[] { 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 5, 4, 4, 3, 2, 1, 6 };
var result = input.Where((x, i) => i == 0 || x != input[i - 1]).ToArray();

You are asking for non-repeating elements, not unique elements. 您要的是非重复元素,而不是唯一元素。 LINQ-to-Objects operations are essentially iterators. LINQ-to-Objects操作本质上是迭代器。 You could write your own iterator method that only yields the first time an item is encountered, eg: 您可以编写自己的迭代器方法,该方法仅在第一次遇到项目时产生,例如:

public static IEnumerable<int> DistinctUntilChanged(this IEnumerable<int> source)
{
    int? previous=null;
    foreach(var item in source)
    {
        if (item!=previous)
        {
            previous=item;
            yield return item;
        }
    }
}

var input = new [] {1,2,3,3,4,5,5,5,6,6,5,4,4,3,2,1,6};
var result=input.DistinctUntilChanged().ToArray();

The result will be : 结果将是:

{1,2,3,4,5,6,5,4,3,2,1,6};

UPDATE 更新

Another option is to use Observable.DistinctUntilChanged from the System.Reactive Library, eg: 另一个选择是使用System.Reactive库中的Observable.DistinctUntilChanged ,例如:

var input = new[] { 1, 2, 3, 3, 4, 5, 5, 5, 6, 6, 5, 4, 4, 3, 2, 1, 6 };
var result = input.ToObservable()
                  .DistinctUntilChanged()
                  .ToEnumerable()
                  .ToArray();

System.Reactive, and Reactive Extensions are meant to handle sequences of events using the basic LINQ operators and more. System.Reactive和Reactive Extensions旨在使用基本的LINQ运算符等来处理事件序列。 It's easy to convert between Observable and Enumerable though, with ToObservable() and ToEnumerable() , so they can be used to handle any collection. 但是,使用ToObservable()ToEnumerable()可以轻松在Observable和Enumerable之间进行转换,因此它们可以用于处理任何集合。 After all, an event sequence is similar to an "infinite" sequence 毕竟,事件序列类似于“无限”序列

UPDATE 2 更新2

In case there's any confusion about the use of int? 如果对int?的使用有任何疑问int? to store the previous number, it's to allow easy comparison even with the first element of the source without actually calling First() on it. 为了存储先前的数字,即使在源中的第一个元素上也可以轻松比较,而无需实际调用First() If it was ,eg int previous=0; 如果是,例如int previous=0; and the first element was 0, the comparison would filter out the first element. 并且第一个元素为0,则比较会过滤掉第一个元素。

By using an int? 通过使用int? in C# or an int option in F# or a Maybe<int> if we have a Maybe monad we can differentiate between no initial value and an initial value of 0. 在C#中,在F#中为int option ,或者在Maybe<int>如果我们有Maybe monad,我们可以区分无初始值和初始值0。

Observable.DistinctUntilChanged uses a flag to check whether we are checking the first element. Observable.DistinctUntilChanged使用一个标志来检查我们是否正在检查第一个元素。 The equivalent code would be: 等效代码为:

    public static IEnumerable<int> NonRepeating(this IEnumerable<int> source)
    {
        int previous =0;
        bool isAssigned=false;
        foreach (var item in source)
        {
            if (!isAssigned || item != previous)
            {
                isAssigned = true;
                previous = item;
                yield return item;
            }
        }
    }

MoreLINQ 更多LINQ

Finally, one can use the GroupAdjacent method from the MoreLinq library to group repeating items together. 最后,可以使用MoreLinq库中的GroupAdjacent方法将重复项组合在一起。 Each group contains the repeating source elements. 每个组包含重复的源元素。 In this particular case though we only need the key values: 在这种特殊情况下,尽管我们只需要键值:

var result = input.GroupAdjacent(i => i).Select(i => i.Key).ToArray();

The nice thing about GroupAdjacent is that the elements can be transformed while grouping, eg : GroupAdjacent是,分组时可以转换元素,例如:

input.GroupAdjacent(i => i,i=>$"Number {i}")

would return groupings of strings. 将返回字符串分组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM