Select 匹配数组中的字段和 C# Linq 的父项
Select fields in a matching array and parent with C# Linq
我有一个对象,我需要从第一个匹配的字段中获取一些字段。关键是“价格”将按升序或降序“基本”顺序排序。找到第一个匹配的“base”并确保“availability.amount”符合条件,最后 return“base”、“priceTypeID”和“priceLevelID”。这是一小段代码,它不能满足我的需要;基本上,一个结果给了我 3 个匹配项,而另一个没有给我“priceLevelID”。
我下面的标准应该 return "base"=4000, "priceTypeID"="45082" and "priceLevelID"="2650"
public class PriceInfo
{
public class Availability
{
public int amount { get; set; }
}
public class Price
{
public int @base { get; set; }
public string priceTypeID { get; set; }
}
public class PriceLevel
{
public string priceLevelID { get; set; }
public Availability availability { get; set; }
public List<Price> prices { get; set; }
}
public class ZonePrice
{
public List<PriceLevel> priceLevels { get; set; }
}
public class OfferPrice
{
public List<ZonePrice> zonePrices { get; set; }
}
public class RootObject
{
public List<OfferPrice> offerPrices { get; set; }
}
}
class Program
{
static void Main(string[] args)
{
var json = @"{
""offerPrices"": [
{
""zonePrices"": [
{
""priceLevels"": [
{
""priceLevelID"": ""1653"",
""availability"": {
""amount"": 296
},
""prices"": [
{
""base"": 2000,
""priceTypeID"": ""45082""
}
]
},
{
""priceLevelID"": ""1029"",
""availability"": {
""amount"": 300
},
""prices"": [
{
""base"": 3000,
""priceTypeID"": ""45082""
}
]
},
{
""priceLevelID"": ""2650"",
""availability"": {
""amount"": 400
},
""prices"": [
{
""base"": 4000,
""priceTypeID"": ""45082""
}
]
}
]
}
]
}
]
}";
var obj = JsonConvert.DeserializeObject<PriceInfo.RootObject>(json);
var queryResult1 = obj.offerPrices[0].zonePrices[0].priceLevels.Where(w => w.availability.amount >= 2 &&
w.prices.OrderByDescending(o => o.@base).Any(w2 => w2.@base > 1000 && w2.@base < 300000)).FirstOrDefault();
var queryResult2 = obj.offerPrices[0].zonePrices[0].priceLevels.Select(o => new { o.prices, o.priceLevelID, o.availability.amount }).
Select(o2 => o2.prices.OrderByDescending(o3 => o3).Where(w => w.@base > 1000 && w.@base < 300000).
Select(s => new { o2.priceLevelID, s.priceTypeID, s.@base, o2.amount }).First()).
Where(w2 => w2.amount > 2).First();
我不清楚你的 selection 标准是什么,但我是这样考虑这个查询的。
首先,select 叶节点,因为您根据它们进行过滤。在这里,我根据您的示例查询做出关于订购的假设:
var ordered = obj.offerPrices
.SelectMany(o => o.zonePrices)
.SelectMany(z => z.priceLevels)
.Select(l => new
{
comparisonPrice = l.prices.MaxBy(p => p.@base).First(), // MaxBy from morelinq. Requires First() because there can be multiple equal base prices
l.priceLevelID,
l.availability
})
.OrderByDescending(l => l.comparisonPrice.@base);
接下来,筛选出所需价格范围内的结果:
var minBase = 1000;
var maxBase = 300000;
var meetsPriceRange = ordered
.Where(o => o.comparisonPrice.@base > minBase &&
o.comparisonPrice.@base < maxBase);
最后,确保所需的最低可用性并选出我们的获胜者:
var minAvailable = 2;
var meetsMinimumAmount = ordered
.Where(o => o.availability.amount >= minAvailable)
.Select(o => new {
o.comparisonPrice.@base,
o.comparisonPrice.priceTypeID,
o.priceLevelID
})
.First();
输出:
base: 4000
priceTypeId: 45082
priceLevelID: 2650
试试这个
var basePriceItem = obj.offerPrices.SelectMany(o => o.zonePrices)
.SelectMany(z => z.priceLevels).SelectMany(s => s.prices).OrderByDescending(o => o.@base)
.FirstOrDefault(b => b.@base > 1000 && b.@base < 300000);
var item = obj.offerPrices.SelectMany(o => o.zonePrices)
.SelectMany(z => z.priceLevels)
.FirstOrDefault(o => o.prices.Any(p => p.priceTypeID == basePriceItem.priceTypeID && p.@base == basePriceItem.@base));
输出
{
"priceLevelID": "2650",
"availability": {
"amount": 400
},
"prices": [
{
"base": 4000,
"priceTypeID": "45082"
}
]
}
我觉得你是在问这个:
var query =
from x in obj.offerPrices[0].zonePrices[0].priceLevels
where x.availability.amount > 2
from y in x.prices
where y.@base > 1000
where y.@base < 300000
orderby y.@base descending
select new { x.priceLevelID, y.priceTypeID, y.@base, x.availability.amount };
var result = query.FirstOrDefault();
这给了我:
var query =
obj
.offerPrices[0]
.zonePrices[0]
.priceLevels
.Where(x => x.availability.amount > 2)
.SelectMany(x =>
x
.prices
.Where(y => y.@base > 1000)
.Where(y => y.@base < 300000)
.OrderByDescending(y => y.@base),
(x, y) => new { x.priceLevelID, y.priceTypeID, y.@base, x.availability.amount });
我有一个对象,我需要从第一个匹配的字段中获取一些字段。关键是“价格”将按升序或降序“基本”顺序排序。找到第一个匹配的“base”并确保“availability.amount”符合条件,最后 return“base”、“priceTypeID”和“priceLevelID”。这是一小段代码,它不能满足我的需要;基本上,一个结果给了我 3 个匹配项,而另一个没有给我“priceLevelID”。
我下面的标准应该 return "base"=4000, "priceTypeID"="45082" and "priceLevelID"="2650"
public class PriceInfo
{
public class Availability
{
public int amount { get; set; }
}
public class Price
{
public int @base { get; set; }
public string priceTypeID { get; set; }
}
public class PriceLevel
{
public string priceLevelID { get; set; }
public Availability availability { get; set; }
public List<Price> prices { get; set; }
}
public class ZonePrice
{
public List<PriceLevel> priceLevels { get; set; }
}
public class OfferPrice
{
public List<ZonePrice> zonePrices { get; set; }
}
public class RootObject
{
public List<OfferPrice> offerPrices { get; set; }
}
}
class Program
{
static void Main(string[] args)
{
var json = @"{
""offerPrices"": [
{
""zonePrices"": [
{
""priceLevels"": [
{
""priceLevelID"": ""1653"",
""availability"": {
""amount"": 296
},
""prices"": [
{
""base"": 2000,
""priceTypeID"": ""45082""
}
]
},
{
""priceLevelID"": ""1029"",
""availability"": {
""amount"": 300
},
""prices"": [
{
""base"": 3000,
""priceTypeID"": ""45082""
}
]
},
{
""priceLevelID"": ""2650"",
""availability"": {
""amount"": 400
},
""prices"": [
{
""base"": 4000,
""priceTypeID"": ""45082""
}
]
}
]
}
]
}
]
}";
var obj = JsonConvert.DeserializeObject<PriceInfo.RootObject>(json);
var queryResult1 = obj.offerPrices[0].zonePrices[0].priceLevels.Where(w => w.availability.amount >= 2 &&
w.prices.OrderByDescending(o => o.@base).Any(w2 => w2.@base > 1000 && w2.@base < 300000)).FirstOrDefault();
var queryResult2 = obj.offerPrices[0].zonePrices[0].priceLevels.Select(o => new { o.prices, o.priceLevelID, o.availability.amount }).
Select(o2 => o2.prices.OrderByDescending(o3 => o3).Where(w => w.@base > 1000 && w.@base < 300000).
Select(s => new { o2.priceLevelID, s.priceTypeID, s.@base, o2.amount }).First()).
Where(w2 => w2.amount > 2).First();
我不清楚你的 selection 标准是什么,但我是这样考虑这个查询的。
首先,select 叶节点,因为您根据它们进行过滤。在这里,我根据您的示例查询做出关于订购的假设:
var ordered = obj.offerPrices
.SelectMany(o => o.zonePrices)
.SelectMany(z => z.priceLevels)
.Select(l => new
{
comparisonPrice = l.prices.MaxBy(p => p.@base).First(), // MaxBy from morelinq. Requires First() because there can be multiple equal base prices
l.priceLevelID,
l.availability
})
.OrderByDescending(l => l.comparisonPrice.@base);
接下来,筛选出所需价格范围内的结果:
var minBase = 1000;
var maxBase = 300000;
var meetsPriceRange = ordered
.Where(o => o.comparisonPrice.@base > minBase &&
o.comparisonPrice.@base < maxBase);
最后,确保所需的最低可用性并选出我们的获胜者:
var minAvailable = 2;
var meetsMinimumAmount = ordered
.Where(o => o.availability.amount >= minAvailable)
.Select(o => new {
o.comparisonPrice.@base,
o.comparisonPrice.priceTypeID,
o.priceLevelID
})
.First();
输出:
base: 4000
priceTypeId: 45082
priceLevelID: 2650
试试这个
var basePriceItem = obj.offerPrices.SelectMany(o => o.zonePrices)
.SelectMany(z => z.priceLevels).SelectMany(s => s.prices).OrderByDescending(o => o.@base)
.FirstOrDefault(b => b.@base > 1000 && b.@base < 300000);
var item = obj.offerPrices.SelectMany(o => o.zonePrices)
.SelectMany(z => z.priceLevels)
.FirstOrDefault(o => o.prices.Any(p => p.priceTypeID == basePriceItem.priceTypeID && p.@base == basePriceItem.@base));
输出
{
"priceLevelID": "2650",
"availability": {
"amount": 400
},
"prices": [
{
"base": 4000,
"priceTypeID": "45082"
}
]
}
我觉得你是在问这个:
var query =
from x in obj.offerPrices[0].zonePrices[0].priceLevels
where x.availability.amount > 2
from y in x.prices
where y.@base > 1000
where y.@base < 300000
orderby y.@base descending
select new { x.priceLevelID, y.priceTypeID, y.@base, x.availability.amount };
var result = query.FirstOrDefault();
这给了我:
var query =
obj
.offerPrices[0]
.zonePrices[0]
.priceLevels
.Where(x => x.availability.amount > 2)
.SelectMany(x =>
x
.prices
.Where(y => y.@base > 1000)
.Where(y => y.@base < 300000)
.OrderByDescending(y => y.@base),
(x, y) => new { x.priceLevelID, y.priceTypeID, y.@base, x.availability.amount });