簡體   English   中英

LINQ訂購-自定義

[英]LINQ OrderBy - Custom

我有一些數據

ID    Sequence  customIndex
1     1         0
2     2         0
3     3         2
4     4         1
5     5         0

我需要按順序使用順序,當customIndex為零時,否則應使用customIndex。

因此,結果應為1,2,4,3,5的ID。

我需要使用Lambda的LINQ實現。 我嘗試了一些解決方案,但無法實現。

由於格式錯誤,發帖重復並刪除了上一篇,我的問題的含義被更改了,我收到了一堆否定票。

在dotnet小提琴上添加了代碼:

https://stable.dotnetfiddle.net/fChl40

這適用於提供的測試數據:

    l.OrderBy(a => a.customIndex != 0 ? 
        list.Where(b => b.Sequence < a.Sequence && b.customIndex == 0)
            .OrderByDescending(c => c.Sequence)
            .FirstOrDefault()
            .Sequence : a.Sequence)
     .ThenBy(c=>c.customIndex )
     .ToList();

這個想法是通過先在前面的零值行對非零值進行排序,然后再對非零值本身進行排序。

答案基於以下假設: CustomIndex大於或等於零:

var result = 
    data.OrderBy(x => x.CustomIndex==0 ? x.Sequence :
            data.Where(y => y.CustomIndex==0 && y.Sequence < x.Sequence)
                .Max(y => (int?)y.Sequence))
        .ThenBy(x => x.CustomIndex);

這是我想要的東西:

    public static void Main()
{
    List<Data> data = new List<Data>();
    data.Add(new Data{ Id=1, Sequence=1, CustomIndex=0});
    data.Add(new Data{ Id=5, Sequence=5, CustomIndex=0});
    data.Add(new Data{ Id=6, Sequence=6, CustomIndex=2});
    data.Add(new Data{ Id=2, Sequence=2, CustomIndex=0});
    data.Add(new Data{ Id=3, Sequence=3, CustomIndex=2});
    data.Add(new Data{ Id=4, Sequence=4, CustomIndex=1});

    data.Add(new Data{ Id=7, Sequence=7, CustomIndex=1});

    int o = 0;
    var result = data
        .OrderBy(x=>x.Sequence).ToList()
        .OrderBy((x)=> myCustomSort(x, ref o) )
            ;       
    result.ToList().ForEach(x=> Console.WriteLine(x.Id));
}

public static float myCustomSort(Data x, ref int o){

    if(x.CustomIndex==0){
        o = x.Sequence;
        return x.Sequence ;
    }
    else 
        return float.Parse(o + "."+ x.CustomIndex);
}

示例代碼: https : //stable.dotnetfiddle.net/fChl40我將進一步完善它

這是不漂亮,但它體現了你問什么,我認為:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        List<Data> data = new List<Data>();
        data.Add(new Data { Id = 1, Sequence = 1, CustomIndex = 0 });
        data.Add(new Data { Id = 2, Sequence = 2, CustomIndex = 0 });
        data.Add(new Data { Id = 3, Sequence = 3, CustomIndex = 2 });
        data.Add(new Data { Id = 4, Sequence = 4, CustomIndex = 1 });
        data.Add(new Data { Id = 5, Sequence = 5, CustomIndex = 0 });

        //List of items where the sequence is what counts
        var itemsToPlaceBySequence = data.Where(x => x.CustomIndex == 0).OrderBy(x => x.Sequence).ToList();
        //List of items where the custom index counts
        var itemsToPlaceByCustomIndex = data.Where(x => x.CustomIndex != 0).OrderBy(x => x.CustomIndex).ToList();

        //Array to hold items
        var dataSlots = new Data[data.Count];

        //Place items by sequence
        foreach(var dataBySequence in itemsToPlaceBySequence) {
            dataSlots[dataBySequence.Sequence - 1] = dataBySequence ;
        }

        //Find empty data slots and place remaining items in CustomIndex order 
        foreach (var dataByCustom in itemsToPlaceByCustomIndex) {
            var index = dataSlots.ToList().IndexOf(null);
            dataSlots[index] = dataByCustom ;
        }

        var result = dataSlots.ToList();

        result.ForEach(x => Console.WriteLine(x.Id));
        var discard = Console.ReadKey();
    }

    public class Data
    {
        public int Id { get; set; }
        public int Sequence { get; set; }
        public int CustomIndex { get; set; }
    }
}

根據您的問題並回復我的評論,我了解您需要對項目集合進行聚類,然后在每個聚類的所有項目上考慮Sequence和CustomIndex。
聚類后​​(根據特定條件分成多個塊),您可以將它們合並回一個唯一的集合中,但是這樣做時,您可以根據需要獨立地操作每個聚類。

public static class extCluster
{
    public static IEnumerable<KeyValuePair<bool, T[]>> Clusterize<T>(this IEnumerable<T> self, Func<T, bool> clusterizer)
    {
        // Prepare temporary data
        var bLastCluster = false;
        var cluster = new List<T>();

        // loop all items
        foreach (var item in self)
        {
            // Compute cluster kind
            var bItemCluster = clusterizer(item);
            // If last cluster kind is different from current
            if (bItemCluster != bLastCluster)
            {
                // If previous cluster was not empty, return its items
                if (cluster.Count > 0)
                    yield return new KeyValuePair<bool, T[]>(bLastCluster, cluster.ToArray());

                // Store new cluster kind and reset items
                bLastCluster = bItemCluster;
                cluster.Clear();
            }

            // Add current item to cluster
            cluster.Add(item);
        }

        // If previous cluster was not empty, return its items
        if (cluster.Count > 0)
            yield return new KeyValuePair<bool, T[]>(bLastCluster, cluster.ToArray());
    }
}
// sample
static class Program
{
    public class Item
    {
        public Item(int id, int sequence, int _customIndex)
        {
            ID = id; Sequence = sequence; customIndex = _customIndex;
        }
        public int ID, Sequence, customIndex;
    }
    [STAThread]
    static void Main(string[] args)
    {
        var aItems = new[]
        {
            new Item(1, 1, 0),
            new Item(2, 2, 0),
            new Item(3, 3, 2),
            new Item(4, 4, 1),
            new Item(5, 5, 0)
        };

        // Split items into clusters
        var aClusters = aItems.Clusterize(item => item.customIndex != 0);
        // Explode clusters and sort their items
        var result = aClusters
            .SelectMany(cluster => cluster.Key
            ? cluster.Value.OrderBy(item => item.customIndex)
            : cluster.Value.OrderBy(item => item.Sequence));
    }
}

您想要執行的排序(部分在CustomIndex上,部分在Sequence上)不能像這樣工作。 但這應該接近您想要的。 首先按CustomIndex排序,然后按Sequence排序。

var result = data.OrderBy(x => x.CustomIndex).ThenBy(x => x.Sequence);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM