Я работаю над экраном, который обеспечивает сравнение между 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
и заполнитьпользовательский интерфейс, как показано ниже:
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необычный предмет, показанный на экране.Я хочу, чтобы все общие и необычные записи отображались в сетке, и очевидно, что необычные записи будут иметь ноль для их противоположного аналога, как показано ниже:

Таким образом, если list1 имеет 28 записей, список 2 имеет 32 записи, из которых 10 являются общими, то экран сравнения результатов должен отображать 10 общих записей и необычные записи из обоих списков.
Я пытался использовать операторы Intersect
, Except
и Concat
, но не смог достичь желаемого результата.Обратите внимание, что RateFactorItem
не имеет поля Id, потому что оно никогда не сохраняется в БД, все рассчитывается на лету и отображается на экране.
Пожалуйста, помогите с указателями.