多条件c#排序
请容忍我,我会尽量不把事情弄得太复杂。我有一份产品清单。产品如下所示:多条件c#排序,c#,sorting,C#,Sorting,请容忍我,我会尽量不把事情弄得太复杂。我有一份产品清单。产品如下所示: { "id": 3797, "title": "Canon EOS 100D Digital SLR Camera with 18-55 IS STM Lens, HD 1080p, 18MP, 3\" LCD Touch Screen", "shortTitle": "Canon EOS 100D Black", "brand": "Canon", "model": "EOS 100
{
"id": 3797,
"title": "Canon EOS 100D Digital SLR Camera with 18-55 IS STM Lens, HD 1080p, 18MP, 3\" LCD Touch Screen",
"shortTitle": "Canon EOS 100D Black",
"brand": "Canon",
"model": "EOS 100D",
"colour": "Black",
"gtin": "8714574602721",
"image": "http://piiick.blob.core.windows.net/images/Canon-EOS-100D-18-55-Black-8714574602721.png",
"type": "Digital SLR",
"lensFocalLength": "18-55",
"lensType": "IS STM",
"lensMount": "EF/EF-S",
"maxAperture": "999",
"connectivity": "",
"shootingModes": "Scene Intelligent Auto (Stills and Movie), No Flash, Creative Auto, Portrait, Landscape, Close-up, Sports, SCN(Kids, Food, Candlelight, Night Portrait, Handheld Night Scene, HDR Backlight Control), Program AE , Shutter priority AE, Aperture priority AE, Manual (Stills and Movie)",
"weight": 410.0,
"width": 116.8,
"height": 90.7,
"depth": 69.4,
"digitalZoom": "N/A",
"opticalZoom": "N/A",
"waterproof": false,
"maxVideoResolution": "1920 x 1080",
"sensorType": "CMOS",
"sensorSize": "22.3 x 14.9 mm",
"continuousShootingSpeed": "4",
"iso": "1600",
"style": "traditional",
"designer": "",
"dateAnnounced": "10/06/2008",
"focusPoints": 7
}
但为了帮助解释这一点,我将简化它。
我正在尝试创建一个排序方法,允许对多个列进行排序。
例如,我有以下方法:
/// <summary>
/// Performs an advanced sort on products using sortations
/// </summary>
/// <param name="products">The products to sort</param>
/// <param name="sortations">The sortation list</param>
public void AdvancedSort(List<JObject> products, List<Sortation> sortations)
{
// Get our value types
GetTypesFromOperator(sortations);
// Sort our products by the sortations
products.Sort((a, b) =>
{
foreach (var sortation in sortations)
{
// Get our values
var fieldName = sortation.Field;
var x = a.SelectToken(fieldName).ToString();
var y = b.SelectToken(fieldName).ToString();
var type = sortation.Type;
// If both values are the same, skip the rest of this iteration
if (x.Equals(y)) return 0;
// If we have an expression
if (!string.IsNullOrEmpty(sortation.Expression))
{
// If we are checking for between
if (sortation.Operator == "><")
{
// Get our values
var values = sortation.Expression.Split(',');
// If we have 2 values
if (values.Length == 2)
return CompareBetween(values, x, y);
}
// If we are checking booleans
if (sortation.Operator == "===")
return CompareBoolean(sortation.Expression);
// If we are checking equals
if (sortation.Operator == "=")
return y.Equals(sortation.Expression) ? 1 : -1;
// If we are checking like
if (sortation.Operator == "%")
return y.Equals(sortation.Expression, StringComparison.OrdinalIgnoreCase) ? 1 : -1;
}
// If we get this far, do a switch on sortation types
switch (sortation.Type)
{
case SortationValueType.Boolean:
return Boolean.Parse(x) ? -1 : 1;
case SortationValueType.Number:
return CompareNumeric(x, y, sortation.Direction);
default:
return string.CompareOrdinal(x, y);
}
}
// If nothing matches, return 0
return 0;
});
}
但我得到的是这个输出:
[
{ colour:'Silver', Importance:'150'},
{ colour:'Black', Importance:'150' },
{ colour:'Black', Importance:'150' },
{ colour:'Black', Importance:'150' },
{ colour:'Silver', Importance:'149' },
{ colour:'Black', Importance:'149' },
{ colour:'Black', Importance:'149' },
{ colour:'Black', Importance:'149' }
]
[
{ colour:'Silver', Importance:'150' },
{ colour:'Silver', Importance:'149' },
{ colour:'Black', Importance:'150' },
{ colour:'Black', Importance:'150' },
{ colour:'Black', Importance:'150' },
{ colour:'Black', Importance:'149' },
{ colour:'Black', Importance:'149' },
{ colour:'Black', Importance:'149' }
]
有人能帮我修正我的排序方法吗?看起来你已经把它们倒过来了-它把所有的“银”放在第一位,然后按重要性排序 尝试交换排序顺序:
var sortations = new List<Sortation>() {
new Sortation() { Field = "importance", Operator = "<" },
new Sortation() { Field = "colour", Operator = "=", Expression = "Silver" }
};
var sortations=新列表(){
new Sortation(){Field=“importance”,Operator=“在我看来,您的基本问题是,一旦第一个Sortation匹配,它就会将sort order值返回给sort函数,其余的Sortation根本不重要。我相信您需要做的是交换foreach和products.sort调用,如下所示:
// Get our value types
GetTypesFromOperator(sortations);
foreach (var sortation in sortations)
{
// Sort our products by the sortations
products.Sort((a, b) =>
{
// Get our values
var fieldName = sortation.Field;
var x = a.SelectToken(fieldName).ToString();
var y = b.SelectToken(fieldName).ToString();
var type = sortation.Type;
....
....
}
}
这将花费更长的时间,但会考虑每个分拣。请记住,列表中的最后一个分拣将是最重要的。如果我这样做,则“白银”将被删除"产品最终位于每个重要区块的底部事实上,它永远不会进入第二个排序。当数据位于某种数据库中时,这类内容非常简单,这样做会比事后手动排序获得更好的性能。如果这些数据最初来自某个数据库,则最好将其转换为如果它不是来自一个数据库,你可能会考虑把它放进一个数据库中。它来自一个API,因此为什么它都在JSON中:DIT工作,我们想说的慢多少?我将永远不会有超过200个产品,而且大概不会超过3个大小,不会慢到打扰你。额外的排序会带来最大的麻烦,因为即使是最有效的排序算法也需要大量计算,但如果最多使用3种排序算法,则所需时间将是原始排序算法的3倍。
var sortations = new List<Sortation>() {
new Sortation() { Field = "importance", Operator = "<" },
new Sortation() { Field = "colour", Operator = "=", Expression = "Silver" }
};
// Get our value types
GetTypesFromOperator(sortations);
foreach (var sortation in sortations)
{
// Sort our products by the sortations
products.Sort((a, b) =>
{
// Get our values
var fieldName = sortation.Field;
var x = a.SelectToken(fieldName).ToString();
var y = b.SelectToken(fieldName).ToString();
var type = sortation.Type;
....
....
}
}