.net 如何对动态类型的数组排序?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.net 如何对动态类型的数组排序?相关的知识,希望对你有一定的参考价值。

//下面的json格式的字符串是从其他接口返回的
string json1 = "persons:[name:\" 张三\",age:20,name:\" 李四\",age:12,name:\" 王五\",age:30]";

var data = JsonConvert.DeserializeObject<dynamic>(json1);

//todo:在这里如何对persons按照age 升序或降序排序

foreach (var item in data.persons)

//这里是我对排序后的结果进行处理的逻辑
string name1 = item.name;
int age = item.age;

//下面的json格式的字符串是从其他接口返回的
string json1 = "persons:[name:\\" 张三\\",age:20,name:\\" 李四\\",age:12,name:\\" 王五\\",age:30]";

            var data = JsonConvert.DeserializeObject<dynamic>(json1);

            //在这里如何对persons按照age 升序或降序排序
            var jada = (IEnumerable<dynamic>) data.persons;
            // var newdata=jada.OrderByDescending(j => j.age);//升序

            var newdata =jada.OrderByDescending(j => j.age);//降序

            //var newdata=jada.OrderByDescending(j => j.age).ThenBy(j=>j.name);//主排序和次排序

            foreach (var item in newdata)
            
                //这里是对排序后的结果进行处理的逻辑
                string name1 = item.name;
                int age = item.age;

            

参考技术A   public class PersonsItem
    
        /// <summary>
        ///  张三
        /// </summary>
        public string name  get; set; 
        /// <summary>
        /// 
        /// </summary>
        public int age  get; set; 
    

    public class Root
    
        /// <summary>
        /// 
        /// </summary>
        public List<PersonsItem> persons  get; set; 
    

直接将你这个json反序列化成Root这个类,List<PersonsItem>排序的话 用linq方便点

追问

我这个json串只是我从接口返回值中拿出的一小部分,整个完整的json串里大概有200以上个字段,我就是不想写那个实体类,采用的dynamic. 这个题目的难点就是对dynamic数组进行排序.
至于你说的linq我知道List.OrderBy(p=>p.age);但不太合适.

如何对具有动态属性的数组进行排序? [复制]

【中文标题】如何对具有动态属性的数组进行排序? [复制]【英文标题】:How to sort an array with dynamic property? [duplicate] 【发布时间】:2019-04-06 07:27:29 【问题描述】:

我有一组电影,我试图根据标记为“路径”的动态值进行排序,该值根据当前的情况评估为“标题”、“流派名称”、“编号InStock”或“每日租借率”状态。然而,因为电影数组中的“流派”属性是一个对象,而不是像其他的字符串,所以我编写的比较函数试图访问movieA(“genre.name”)和movieB(“genre.name”)。我认为这种语法可能有效,但它没有。当然,必须有一种优雅的方式来编写我的比较函数,而不需要在路径设置为“genre.name”时添加更多条件?非常感谢任何帮助或见解。谢谢。(下面是一些代码 sn-ps)

var movies = [
    
        title: "Terminator",
        genre:  _id: "5b21ca3eeb7f6fbccd471818", name: "Action" ,
        numberInStock: 6,
        dailyRentalRate: 2.5,
    ,
    
        title: "Die Hard",
        genre:  _id: "5b21ca3eeb7f6fbccd471818", name: "Action" ,
        numberInStock: 5,
        dailyRentalRate: 2.5
    ,
    
        title: "Get Out",
        genre:  _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" ,
        numberInStock: 8,
        dailyRentalRate: 3.5
    
]

this.state = 
    path: "title"  //'title' or 'genre.name' or 'numberInStock' or 'dailyRentalRate'
;

myCompare = (a, b) => 
    const path  = this.state.path;

    if (a[path] < b[path]) return - 1;
    if (a[path] > b[path]) return 1;
    return 0;


const moviesSorted = movies.sort(this.myCompare);

【问题讨论】:

【参考方案1】:

当路径包含句点时,您应该将其转换为带有split 的数组,然后使用reduce 对其进行迭代并找到您尝试排序的嵌套值:

var movies = [
    
        title: "foo bar",
        genre:  _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" ,
        numberInStock: 8,
        dailyRentalRate: 3
    ,
    
        title: "Terminator",
        genre:  _id: "5b21ca3eeb7f6fbccd471818", name: "Action" ,
        numberInStock: 6,
        dailyRentalRate: 2.5,
    ,
    
        title: "Die Hard",
        genre:  _id: "5b21ca3eeb7f6fbccd471818", name: "Action" ,
        numberInStock: 5,
        dailyRentalRate: 2
    ,
    
        title: "Get Out",
        genre:  _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" ,
        numberInStock: 8,
        dailyRentalRate: 3.5
    
];

let path = "title";

const getNested = (obj, path) => path.split('.').reduce((a, prop) => a[prop], obj);
const myCompare = (a, b) => 
  const aVal = getNested(a, path);
  return typeof aVal === 'string'
  ? aVal.localeCompare(getNested(b, path))
  : aVal - getNested(b, path);
;

// Sort by title:
movies.sort(myCompare);
console.log(movies);

// Sort by genre.name:
path = 'genre.name';
movies.sort(myCompare);
console.log(movies);

【讨论】:

【参考方案2】:

或许,您可以编写一个辅助函数来获取嵌套值,如下所示:

function getNestedValue(fieldName, item) 
    if (fieldName.includes('.')) 
        const keyArr = fieldName.split('.');
        let result = item;
        if (keyArr.length > 1) 
            for (const key of keyArr) 
                result = result[key];
            

            return result;
        
    

    return item[fieldName];


myCompare = (a, b) => 
    const  path  = this.state.sortColumn;
    const valueA = getNestedValue(path, a);
    const valueB = getNestedValue(path, b)

    if (valueA < valueB) return - 1;
    if valueA > valueB) return 1;
    return 0;

并比较给定的结果。

【讨论】:

以上是关于.net 如何对动态类型的数组排序?的主要内容,如果未能解决你的问题,请参考以下文章

冒泡排序不适用于对 C++ 中的动态对象数组进行排序

如何对具有动态属性的数组进行排序? [复制]

asp.net 数组排序

使用 .Net 如何使用 Sort 方法对数组进行反向排序,即从 Z 到 A?

java自动排序函数.......

根据属性的动态列表对 Swift 数组进行排序