根据公共字段对多个列表进行排序

时间:2019-11-27 13:37:10

标签: c# linq

我有这样的类结构。

public class Video
{
   public string URL { get; set; }
    public int Order { get; set; }
}

public class Image
{
    public string Name { get; set; }
    public int Order { get; set; }

}

public class Product
{
    public List<Video> videoList { get; set; }
    public List<Image> imageList { get; set; }
}

我需要显示视频和图像的合并列表中按字段顺序按值排序的视频和图像。

我尝试过的事情

  1. 我将两个列表都转换为对象列表并将其连接起来。

问题:我丢失了字段Order,因此无法排序。

  1. 我将List<Video>投射到List<Images>,然后将其串联起来。

问题:我收不到视频的URL

请告知如何实现相同的目标。 请注意,示例中的类仅用于说明。实际上,所有类都具有20多个字段。

编辑1

这是旧代码,Order字段具有不同的来源。因此,不能遵循@jcruz

建议的方法

4 个答案:

答案 0 :(得分:0)

您应为图像和视频对象使用通用的interface。这将保留所有常用属性,并允许您根据其进行访问和排序。

public interface IMedia
{
    public int Order;
}

public class Video : IMedia
{
   public string URL { get; set; }
   public int Order { get; set; }
}

public class Image : IMedia
{
    public string Name { get; set; }
    public int Order { get; set; }
}

然后使用List<IMedia>代替,您将能够对界面字段进行排序。

List<IMedia> list = new List<IMedia>();
list.OrderBy(i => i.Order);

HTH

答案 1 :(得分:0)

我将尝试增强@jcruz的答案,因为您不能修改Image和Video类。我希望您可以从它们派生出来(它们不是密封的),并假设它们具有诸如public Video(Video origin) {...}之类的构造函数(或者您可以使用其构造函数来恢复它们的状态),请尝试执行以下操作:

public class Video
{
    public string URL { get; set; }
    public int Order { get; set; }
}

public class Image
{
    public string Name { get; set; }
    public int Order { get; set; }

}

public class Product
{
    public List<Video> videoList { get; set; }
    public List<Image> imageList { get; set; }

    public List<IOrdered> OrderedStuff => 
        videoList
        .Select(x => new VideoInterfaced(x) as IOrdered)
        .Union(imageList.Select(x => new ImageInterfaced(x) as IOrdered))
        .OrderBy(x => x.Order)
        .ToList();
}


public interface IOrdered
{
    int Order { get; set; }
}

public class VideoInterfaced : Video, IOrdered
{
    public VideoInterfaced(Video origin) : base(origin)
    {
        //...
    }
}

public class ImageInterfaced : Image, IOrdered
{
    public ImageInterfaced(Image origin) : base(origin)
    {
        //...
    }
}

答案 2 :(得分:0)

此示例假设“图像到视频”为1到1。

public class ProductData
{
    public Video Video {get;set;}
    public Image Image {get;set;}
}

public IDictionary<int,ProductData> AggrigateData(List<Video> videos, List<Image> images)
{
    var orderedSet = images.OrderBy(image => image.Order);
    return videos.ToDictonary(video => video.Order, video => new ProductData {Video = video, Image = orderedSet.FirstOrDefault(image => image.Order == video.Order))}
}

答案 3 :(得分:0)

您仍然可以使用Cast as Object方法,但是将其作为匿名类型的一部分。例如,

var result = product.videoList.Select(x=> new {Data = (object)x,Order=x.Order})
                 .Concat(product.imageList.Select(c=>new {Data = (object)c,Order=c.Order}))
                 .OrderBy(x=>x.Order);