根据对象的嵌套列表对对象列表进行排序



我有一个对象列表,我想在多个条件下排序,对于前两个条件,我可以做到,但是对于最后一个条件,我很难找到实现它的方法。

我想先按gamme排序,然后按序列排序,最后按特征列表排序,这取决于我事先知道的某个顺序。

在这种情况下,我希望最后的排序将遵循以下顺序,这个列表是动态的,所以顺序可能会改变:

["largeur";longueur";epaisseur"; "type_pose"]按值当然。

我现在被这个卡住了:

listOfProducts.OrderBy(c => c.gamme).ThenBy(c => c.serie); 
[
{
"uid": "QB32-20220621-10096",
"gamme": "ATENEA",
"serie": "ALASKA",
"caracteristiques": [
{
"nom": "type_pose",
"label": null,
"valeur": "Pose collée ou scellée selon les dispositions des textes de mise en œuvre"
},
{
"nom": "type_carreau",
"label": null,
"valeur": "Grès pressé émaillé"
},
{
"nom": "groupe_absorption",
"label": null,
"valeur": "Bla"
},
{
"nom": "usage exterieur",
"label": null,
"valeur": "Conforme"
},
{
"nom": "glissance",
"label": null,
"valeur": "Non revendiqué"
},
{
"nom": "finition",
"label": null,
"valeur": "Lisses"
},
{
"nom": "largeur",
"label": null,
"valeur": "500"
},
{
"nom": "longueur",
"label": null,
"valeur": "500"
},
{
"nom": "epaisseur",
"label": null,
"valeur": "9"
},
{
"nom": "particularite",
"label": null,
"valeur": "Non rectifié"
},
{
"nom": "part_produit",
"label": null,
"valeur": "nc"
},
{
"nom": "ref_commerciale_f",
"label": null,
"valeur": ""
},
{
"nom": "coloris_f",
"label": null,
"valeur": "Blanco"
},
{
"nom": "option",
"label": null,
"valeur": "/"
},
{
"nom": "classement",
"label": null,
"valeur": "U3 P3 E3 C2"
}
]
},
{
"uid": "QB32-20220621-10177",
"gamme": "ATENEA",
"serie": "ALOE",
"caracteristiques": [
{
"nom": "type_pose",
"label": null,
"valeur": "Pose collée ou scellée selon les dispositions des textes de mise en œuvre"
},
{
"nom": "type_carreau",
"label": null,
"valeur": "Grès pressé non émaillé"
},
{
"nom": "groupe_absorption",
"label": null,
"valeur": "Bla"
},
{
"nom": "usage exterieur",
"label": null,
"valeur": "Conforme"
},
{
"nom": "glissance",
"label": null,
"valeur": "Non revendiqué"
},
{
"nom": "finition",
"label": null,
"valeur": "Décorés"
},
{
"nom": "largeur",
"label": null,
"valeur": "607.5"
},
{
"nom": "longueur",
"label": null,
"valeur": "607.5"
},
{
"nom": "epaisseur",
"label": null,
"valeur": "9.6"
},
{
"nom": "particularite",
"label": null,
"valeur": "Non rectifié"
},
{
"nom": "part_produit",
"label": null,
"valeur": "nc"
},
{
"nom": "ref_commerciale_f",
"label": null,
"valeur": ""
},
{
"nom": "coloris_f",
"label": null,
"valeur": "Taupe"
},
{
"nom": "option",
"label": null,
"valeur": "/"
},
{
"nom": "classement",
"label": null,
"valeur": "U4 P4 E3 C2"
}
]
},
{
"uid": "QB32-20220621-10054",
"gamme": "CASA INFINITA",
"serie": "IN TIME LAPPATO",
"caracteristiques": [
{
"nom": "type_pose",
"label": null,
"valeur": "Pose collée ou scellée selon les dispositions des textes de mise en œuvre"
}
]
}
]

您可以按子数组中的值排序:

listOfProducts
.OrderBy(c => c.gamme)
.ThenBy(c => c.serie)
.ThenBy(c => c.caracteristiques
.FirstOrDefault(x => x.nom == "largeur")?.valeur)
.ThenBy(c => c.caracteristiques
.FirstOrDefault(x => x.nom == "longueur")?.valeur)
.ThenBy(c => c.caracteristiques
.FirstOrDefault(x => x.nom == "epaisseur")?.valeur)
.ThenBy(c => c.caracteristiques
.FirstOrDefault(x => x.nom == "type_pose")?.valeur); 

在动态属性列表的情况下,您可以动态构建Linq查询:

var dynamicCriteria = new string[] { "largeur","longueur","epaisseur","type_pose" }; 
var sorted = listOfProducts
.OrderBy(c => c.gamme)
.ThenBy(c => c.serie);
foreach (var crit in dynamicCriteria) 
{
sorted = sorted.ThenBy(c => c.caracteristiques
.FirstOrDefault(x => x.nom == crit)?.valeur);
}

上面的代码首先在子数组中搜索具有特定名称的项,然后返回该项的值进行排序比较。

这种基于linq的方法的缺点是子数组被搜索多次。如果您需要在多个场合进行比较,并且有很多caracteristiques,您可以使用IComparer<T>接口实现自定义比较器,或者使用IComparable<T>接口使类具有可比性。在CompareCompareTo方法中,您可以以更有效的方式实现比较。下面的示例显示了一个简单的比较器(根据您的需要进行调整):

public class MyComparer : IComparer<Item> 
{
private readonly IEnumerable<string> _dynamicCriteria; 

public MyComparer(IEnumerable<string> dynamicCriteria) 
{
_dynamicCriteria = dynamicCriteria;
}

public int Compare(Item a, Item b) 
{
// Check static criteria
var result = string.Compare(a.gamme, b.gamme);
if (result != 0)
return result;
result = string.Compare(a.serie, b.serie);
if (result != 0)
return result;
// Get values for dynamic criteria
var dynamicValuesA = a.caracteristiques
.Where(x => _dynamicCriteria.Contains(x.nom))
.ToDictionary(x => x.nom, x => x.valeur);
var dynamicValuesB = b.caracteristiques
.Where(x => _dynamicCriteria.Contains(x.nom))
.ToDictionary(x => x.nom, x => x.valeur);
// Compare dynamic criteria
foreach (var crit in _dynamicCriteria) 
{
string valueA;
if (!dynamicValuesA.TryGetValue(crit, out valueA))
valueA = string.Empty;
string valueB;
if (!dynamicValuesB.TryGetValue(crit, out valueB))
valueB = string.Empty;
result = string.Compare(valueA, valueB);
if (result != 0)
return result;
}
// No difference in dynamic criteria, items are equal
return 0;
}
}

你可以像这样使用这个比较器:

var dynamicCriteria = new string[] { "largeur","longueur","epaisseur","type_pose" }; 
var sorted = listOfProducts
OrderBy(c => c, new MyComparer(dynamicCriteria));

相关内容

  • 没有找到相关文章

最新更新