我正在使用一个屏幕,基本上可以比较2 lists
。
我有一个类RateFactorItem
,其中包含一个Name
属性和一个ProductValues
列表。
public class RateFactorItem
{
public string Name { get; set; }
public List<ProductValues> ProductValues { get; set; }
}
ProductValues
类的定义为:
public class ProductValues
{
public string ProductName { get; set; }
public double? Value { get; set; }
}
我还有一个名为CompareViewModel
的类,用于填充比较屏幕。
public class CompareViewModel
{
public string ColumnName { get; set; }
public double? VersionA { get; set; }
public double? VersionB { get; set; }
public double? Variance { get; set; }
}
现在我有2个RateFactorItem
列表,使用几种方法填充,示例代码如下。
public static List<RateFactorItem> GetRecordsA()
{
var items = new List<RateFactorItem>
{
new RateFactorItem
{
Name = "Item1",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=200},
new ProductValues{ ProductName="product2", Value=300},
new ProductValues{ ProductName="product3", Value=400},
new ProductValues{ ProductName="product4", Value=500},
new ProductValues { ProductName = "product5", Value = 1000 },
}
},
new RateFactorItem
{
Name = "Item2",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=250},
new ProductValues{ ProductName="product2", Value=350},
new ProductValues{ ProductName="product3", Value=450},
new ProductValues{ ProductName="product4", Value=550},
new ProductValues { ProductName = "product5", Value = 1050 },
}
},
new RateFactorItem
{
Name = "Item3",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=2300},
new ProductValues{ ProductName="product2", Value=3030},
new ProductValues{ ProductName="product3", Value=4040},
new ProductValues{ ProductName="product4", Value=5030},
new ProductValues { ProductName = "product5", Value = 1400 },
}
},
new RateFactorItem
{
Name = "ItemX",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=20},
new ProductValues{ ProductName="product2", Value=30},
new ProductValues{ ProductName="product3", Value=40},
new ProductValues{ ProductName="product4", Value=50 },
new ProductValues { ProductName = "product5", Value = 60 },
}
}
};
return items;
}
public static List<RateFactorItem> GetRecordsB()
{
var items = new List<RateFactorItem>
{
new RateFactorItem
{
Name = "Item1",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=230},
new ProductValues{ ProductName="product2", Value=340},
new ProductValues{ ProductName="product3", Value=470},
new ProductValues{ ProductName="product4", Value=590},
new ProductValues { ProductName = "product5", Value = 1010 },
}
},
new RateFactorItem
{
Name = "Item2",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=220},
new ProductValues{ ProductName="product2", Value=370},
new ProductValues{ ProductName="product3", Value=400},
new ProductValues{ ProductName="product4", Value=510},
new ProductValues { ProductName = "product5", Value = 150 },
}
},
new RateFactorItem
{
Name = "Item3",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=2900},
new ProductValues{ ProductName="product2", Value=3930},
new ProductValues{ ProductName="product3", Value=4940},
new ProductValues{ ProductName="product4", Value=5930},
new ProductValues { ProductName = "product5", Value = 1900 },
}
},
new RateFactorItem
{
Name = "ItemY",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=40},
new ProductValues{ ProductName="product2", Value=80},
new ProductValues{ ProductName="product3", Value=90},
new ProductValues{ ProductName="product4", Value=60 },
new ProductValues { ProductName = "product5", Value = 70 },
}
}
};
return items;
}
在控制器操作方法中,我尝试创建CompareViewModel
的列表并按如下所示填充UI:
public IActionResult Index()
{
var model = new List<CompareViewModel>();
var productNameA = "product1";
var productNameB = "product1";
var recordsA = Records.GetRecordsA();
var recordsB = Records.GetRecordsB();
var countA = recordsA.Count();
var countB = recordsB.Count();
for (int i = 0; i < Math.Max(countA, countB); i++)
{
var itemName = countA > countB ? recordsA[i].Name : recordsB[i].Name;
var recordA = recordsA.Where(x => x.Name == itemName)?.FirstOrDefault();
var recordB = recordsB.Where(x => x.Name == itemName)?.FirstOrDefault();
var subModel = new CompareViewModel
{
ColumnName = itemName,
VersionA = recordA != null ? (recordA.ProductValues.Where(x => x.ProductName == productNameA).FirstOrDefault()?.Value ?? 0) : 0,
VersionB = recordB != null ? (recordB.ProductValues.Where(x => x.ProductName == productNameB).FirstOrDefault()?.Value ?? 0) : 0,
Variance = ((recordA != null ? (recordA.ProductValues.Where(x => x.ProductName == productNameA).FirstOrDefault()?.Value ?? 0) : 0) - (recordB != null ? (recordB.ProductValues.Where(x => x.ProductName == productNameB).FirstOrDefault()?.Value ?? 0) : 0))
};
model.Add(subModel);
}
return View(model);
}
出于演示目的,我在recordsA
和recordsB
中的项目数相同,但是在实时情况下,项目数可以不同。
在上面的示例中,比较屏幕填充如下:
仅显示共同的项目Item1,Item2,Item3,而在屏幕上仅显示1个不常见的项目。 我希望所有常见和不常见的记录都应显示在网格中,显然,不常见的记录的相对应记录为零,如下所示:
因此,如果列表1有28条记录,列表2有32条记录,其中10条是公共记录,那么结果比较屏幕应显示10个公共记录和两个列表中的罕见记录。
我尝试使用Intersect
,Except
和Concat
运算符,但无法获得所需的结果。
请注意,RateFactorItem
没有ID字段,因为这些字段从未存储在数据库中,而是全部在运行时计算并显示在屏幕上。
请协助指导。
答案 0 :(得分:0)
我用结果构建了一个数据表
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
List<RateFactorItem> recordA = GetRecordsA();
List<RateFactorItem> recordB = GetRecordsB();
var results = (from a in recordA
join b in recordB on a.Name equals b.Name
select new { a = a, b = b, name = a.Name}
)
.Select(x => (from ap in x.a.ProductValues
join bp in x.b.ProductValues on ap.ProductName equals bp.ProductName into abp
from bp in abp.DefaultIfEmpty()
select new { ap = ap, bp = bp, name = x.name }
).ToList()
).ToList();
DataTable dt = new DataTable();
dt.Columns.Add("Item", typeof(string));
dt.Columns.Add("product", typeof(string));
dt.Columns.Add("A Quantity", typeof(int));
dt.Columns.Add("B Quantity", typeof(int));
dt.Columns.Add("Variance", typeof(int));
foreach (var item in results)
{
foreach (var product in item)
{
DataRow newRow = dt.Rows.Add(new object[] {
product.name,
product.ap.ProductName,
product.ap.Value,
product.bp.Value,
(product.bp.Value == null) ? (int)product.ap.Value : Math.Abs((int)product.ap.Value - (int)product.bp.Value)
});
}
}
dataGridView1.DataSource = dt;
}
public static List<RateFactorItem> GetRecordsA()
{
var items = new List<RateFactorItem>
{
new RateFactorItem
{
Name = "Item1",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=200},
new ProductValues{ ProductName="product2", Value=300},
new ProductValues{ ProductName="product3", Value=400},
new ProductValues{ ProductName="product4", Value=500},
new ProductValues { ProductName = "product5", Value = 1000 },
}
},
new RateFactorItem
{
Name = "Item2",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=250},
new ProductValues{ ProductName="product2", Value=350},
new ProductValues{ ProductName="product3", Value=450},
new ProductValues{ ProductName="product4", Value=550},
new ProductValues { ProductName = "product5", Value = 1050 },
}
},
new RateFactorItem
{
Name = "Item3",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=2300},
new ProductValues{ ProductName="product2", Value=3030},
new ProductValues{ ProductName="product3", Value=4040},
new ProductValues{ ProductName="product4", Value=5030},
new ProductValues { ProductName = "product5", Value = 1400 },
}
},
new RateFactorItem
{
Name = "ItemX",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=20},
new ProductValues{ ProductName="product2", Value=30},
new ProductValues{ ProductName="product3", Value=40},
new ProductValues{ ProductName="product4", Value=50 },
new ProductValues { ProductName = "product5", Value = 60 },
}
}
};
return items;
}
public static List<RateFactorItem> GetRecordsB()
{
var items = new List<RateFactorItem>
{
new RateFactorItem
{
Name = "Item1",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=230},
new ProductValues{ ProductName="product2", Value=340},
new ProductValues{ ProductName="product3", Value=470},
new ProductValues{ ProductName="product4", Value=590},
new ProductValues { ProductName = "product5", Value = 1010 },
}
},
new RateFactorItem
{
Name = "Item2",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=220},
new ProductValues{ ProductName="product2", Value=370},
new ProductValues{ ProductName="product3", Value=400},
new ProductValues{ ProductName="product4", Value=510},
new ProductValues { ProductName = "product5", Value = 150 },
}
},
new RateFactorItem
{
Name = "Item3",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=2900},
new ProductValues{ ProductName="product2", Value=3930},
new ProductValues{ ProductName="product3", Value=4940},
new ProductValues{ ProductName="product4", Value=5930},
new ProductValues { ProductName = "product5", Value = 1900 },
}
},
new RateFactorItem
{
Name = "ItemY",
ProductValues = new List<ProductValues>
{
new ProductValues{ ProductName="product1", Value=40},
new ProductValues{ ProductName="product2", Value=80},
new ProductValues{ ProductName="product3", Value=90},
new ProductValues{ ProductName="product4", Value=60 },
new ProductValues { ProductName = "product5", Value = 70 },
}
}
};
return items;
}
}
public class RateFactorItem
{
public string Name { get; set; }
public List<ProductValues> ProductValues { get; set; }
}
public class ProductValues
{
public string ProductName { get; set; }
public double? Value { get; set; }
}
}