Sha*_*eek 15 c# linq ienumerable
我创建了两个名为X&Y的列表.这两个列表的类型不同.(即List<class_A> X&List<class_B> Y).
这两个列表中的值都不同.但是这DateTime两个列表中都有一个字段.
我需要根据date字段对这些列表进行排序.
我有单独的函数来打印列表A和列表B的详细信息.
假设排序列表看起来像
我的目的是遍历此列表并调用相应的函数来显示详细信息.即,如果元组来自列表A,则调用函数打印列表A的详细信息,反之亦然.
sla*_*win 27
您可以创建一个interface托管公共属性和函数的函数,然后在转换为此接口后将这些列表连接起来然后对其进行排序:
interface ICommon
{
DateTime DT { get; }
void Print();
}
class ClassA : ICommon
{
public DateTime DT { get; set; }
public void Print() { Console.WriteLine("A " + DT); }
}
class ClassB : ICommon
{
public DateTime DT { get; set; }
public void Print() { Console.WriteLine("B " + DT); }
}
public static void Main()
{
var listA = new List<ClassA> { new ClassA() { DT = DateTime.Now.AddDays(-1) }, new ClassA() { DT = DateTime.Now.AddDays(-3) }};
var listB = new List<ClassB> { new ClassB() { DT = DateTime.Now.AddDays(-2) }, new ClassB() { DT = DateTime.Now.AddDays(-4) }};
var orderedResult = listA.Cast<ICommon>()
.Concat(listB.Cast<ICommon>())
.OrderBy(q => q.DT);
//or possibly even better:
//var orderedResult = listA.Concat<ICommon>(listB).OrderBy(q => q.DT);
foreach (var obj in orderedResult)
obj.Print();
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*son 22
如果你可以改变类A和类的定义,B那么你应该使用其中一个其他答案,告诉你为这两个类添加一个接口.
但是,如果您无法更改类A和类的定义B(可能是因为它们是在您无法更改的库中定义的),那么您必须采用不同的方法.
一个保持相当整洁的解决方案是引入一个包装类,它包含类A或类的实例B(但不包括两者).
假设您的类看起来像这样:
class A
{
public DateTime Date;
public double Value;
public void Print() {}
}
class B
{
public DateTime Date;
public string Value;
public void Print() { }
}
Run Code Online (Sandbox Code Playgroud)
您可以编写一个如下所示的简单包装器:
class Wrapper
{
readonly A a;
readonly B b;
public Wrapper(A a)
{
this.a = a;
}
public Wrapper(B b)
{
this.b = b;
}
public DateTime Date => a?.Date ?? b.Date;
public void Print()
{
if (a != null)
a.Print();
else
b.Print();
}
}
Run Code Online (Sandbox Code Playgroud)
然后给出两个列表:
var listA = new List<A>();
var listB = new List<B>();
Run Code Online (Sandbox Code Playgroud)
您可以创建Wrapper对象的排序列表:
var sorted =
listA.Select(a => new Wrapper(a))
.Concat(listB.Select(b => new Wrapper(b)))
.OrderBy(item => item.Date);
Run Code Online (Sandbox Code Playgroud)
然后为Print()排序列表中的每个项调用适当的方法:
foreach (var item in sorted)
item.Print();
Run Code Online (Sandbox Code Playgroud)
如果你制作Class A并Class B以a为基础Base class,你可以让他们从中获得你的DateTime财产Base class.
例如:
public class BaseClass
{
public DateTime date {get; set; }
}
public class ClassA : BaseClass
{
//... some other property's
}
public class ClassB : BaseClass
{
//... some other property's
}
Run Code Online (Sandbox Code Playgroud)
在你的代码中:
List<BaseClass> a = new List<ClassA>();
List<BaseClass> b = new List<ClassB>();
Run Code Online (Sandbox Code Playgroud)
因为ClassA和ClassB基于BaseClass,它们将具有相同的date属性.
您可以为您拥有的2个类创建一个简单的界面:
public interface interfaceA {
DateTime TimeStamp { get;set; }
}
Run Code Online (Sandbox Code Playgroud)
并确保您的类都实现该接口:
public class class_A : interfaceA {
public DateTime TimeStamp { get; set; }
//... Other properties
}
public class class_B : interfaceA {
public DateTime TimeStamp { get; set; }
//... Other properties
}
Run Code Online (Sandbox Code Playgroud)
在您的主函数/方法中,您创建一个包含两种对象类型并填充它的新List - 而不是填充您的2个列表中的一个,您只需填写以下列表:
var myList = new List<interfaceA>();
var object = new class_A() { TimeStamp = DateTime.Now };
myList.Add(object);
Run Code Online (Sandbox Code Playgroud)
然后对它进行排序:
myList.Sort((a, b) => a.TimeStamp.CompareTo(b.TimeStamp))
Run Code Online (Sandbox Code Playgroud)
我觉得这样的事情应该有效
无需创建新的接口或类.您可以同时遍历两个列表并跟踪最近的日期.
public class TypeA
{
public DateTime date { get; set; }
public void Print() { Console.WriteLine("TypeA: " + date.ToString()); }
}
public class TypeB
{
public DateTime date { get; set; }
public void Print() { Console.WriteLine("TypeB: " + date.ToString()); }
}
class Program
{
static void Main(string[] args)
{
// setup
var X = new List<TypeA>();
var Y = new List<TypeB>();
Random rnd = new Random();
int imin, imax;
imin = rnd.Next(3, 7);
imax = rnd.Next(10, 20);
for (int i = imin; i < imax; i++)
{
X.Add(new TypeA() { date = DateTime.Now.AddDays(-1 * rnd.Next(1, 1000)) });
}
imin = rnd.Next(3, 7);
imax = rnd.Next(10, 20);
for (int i = imin; i < imax; i++)
{
Y.Add(new TypeB() { date = DateTime.Now.AddDays(-1 * rnd.Next(1, 1000)) });
}
X = X.OrderBy(z => z.date).ToList();
Y = Y.OrderBy(z => z.date).ToList();
// begin print in order
// index for X list
int ix = 0;
// index for Y list
int iy = 0;
// most recently printed date
DateTime min = DateTime.MinValue;
while (true)
{
if (ix < X.Count && X[ix].date >= min && (iy >= Y.Count || iy < Y.Count && X[ix].date <= Y[iy].date))
{
X[ix].Print();
min = X[ix].date;
ix++;
continue;
}
if (iy < Y.Count && Y[iy].date >= min)
{
Y[iy].Print();
min = Y[iy].date;
iy++;
}
if (ix >= X.Count && iy >= Y.Count)
{
break;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
样本输出:
TypeB: 12/19/2013 3:44:44 PM
TypeB: 2/19/2014 3:44:44 PM
TypeB: 5/1/2014 3:44:44 PM
TypeA: 5/27/2014 3:44:44 PM
TypeA: 6/6/2014 3:44:44 PM
TypeA: 7/12/2014 3:44:44 PM
TypeA: 7/18/2014 3:44:44 PM
TypeB: 12/5/2014 3:44:44 PM
TypeB: 5/3/2015 3:44:44 PM
TypeB: 5/4/2015 3:44:44 PM
TypeB: 8/9/2015 3:44:44 PM
TypeA: 8/25/2015 3:44:44 PM
TypeA: 9/20/2015 3:44:44 PM
TypeB: 9/26/2015 3:44:44 PM
TypeA: 10/12/2015 3:44:44 PM
TypeA: 12/7/2015 3:44:44 PM
TypeB: 12/19/2015 3:44:44 PM
TypeA: 4/13/2016 3:44:44 PM
TypeA: 5/23/2016 3:44:44 PM
TypeB: 8/4/2016 3:44:44 PM
TypeB: 8/11/2016 3:44:44 PM
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5875 次 |
| 最近记录: |