对数字和文本的多维对象数组进行排序

Posted

技术标签:

【中文标题】对数字和文本的多维对象数组进行排序【英文标题】:Sorting Multidimensional Array of Objects for Both Numbers and Text 【发布时间】:2020-09-02 06:20:46 【问题描述】:
var customers = [
  'Name' : 'John', 'Attributes' : 'Age' : 5, 'Height' : 1.5, 'Country': 'USA', 'Clothes' : 'Shirts' : 5, 'Pants' : 8, 
  'Name' : 'Andrew', 'Attributes' : 'Age' : 9, 'Height' : 1.8, 'Country': 'Canada', 'Clothes' : 'Shirts' : 2, 'Pants' : 5, 
  'Name' : 'Lucifer', 'Attributes' : 'Age' : 11, 'Height' : 1.3, 'Country': 'France', 'Clothes' : 'Shirts' : 9, 'Pants' : 4
];

function sort(valuePath, array)
  let path = valuePath.split('.')  

  return array.sort((a, b) => 
     return getValue(b,path) -  getValue(a,path)    
  );

  function getValue(obj, path)
    path.forEach(path => obj = obj[path])
    return obj;
  

如果我触发,我有这个功能的工作结构:

sort('Attributes.Height', customers)

但如果我选择使用文本,它就不起作用,例如:

sort('Attributes.Country', customers)

如何应用必要的修改?感谢您的宝贵时间。

【问题讨论】:

【参考方案1】:

按字符串排序的工作方式不同,请从here 阅读。想法是首先检测您应用的键类型是数字还是字符串,然后相应地应用排序。

var customers = [ 'Name' : 'Andrew', 'Attributes' : 'Age' : 9, 'Height' : 1.8, 'Country': 'Canada', 'Clothes' : 'Shirts' : 2, 'Pants' : 5, 'Name' : 'John', 'Attributes' : 'Age' : 5, 'Height' : 1.5, 'Country': 'USA', 'Clothes' : 'Shirts' : 5, 'Pants' : 8, 'Name' : 'Lucifer', 'Attributes' : 'Age' : 11, 'Height' : 1.3, 'Country': 'France', 'Clothes' : 'Shirts' : 9, 'Pants' : 4];

function sort(valuePath, array)
  let path = valuePath.split('.')  
  let value = getType(array[0],path);
  
  if(value == 'string')
     return array.sort((a, b) => (getValue(a,path).toUpperCase() > getValue(b,path).toUpperCase()) - (getValue(a,path).toUpperCase() < getValue(b,path).toUpperCase()))
   else 
     return array.sort((a, b) => getValue(a,path) -  getValue(b,path));
  
 
 function getValue(obj, path)
    path.forEach(path => obj = obj[path])
    return obj;
  
 
  function getType(obj, path)
    path.forEach(path => obj = obj[path])
    return typeof obj;
  


console.log(sort('Attributes.Country', customers));
console.log(sort('Attributes.Height', customers));

【讨论】:

【参考方案2】:

您可以使用&lt;&gt; 运算符比较值,而不是使用减号运算符进行数学比较。这适用于数字和字符串。

  return array.sort((a, b) => 
     if (getValue(a,path) < getValue(b,path)) 
       return -1;
     
     if (getValue(a,path) > getValue(b,path)) 
       return 1;
     
     return 0;
  );

见:https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Array/sort#Description

【讨论】:

【参考方案3】:

您可以采用一种适用于数字和字符的排序方法,并在路径和排序顺序上使用闭包。

此方法通过将数组作为第一个参数来使用更改的参数顺序。

const
    sort = (array, valuePath, order = 'ASC') => 
        const
            getValue =
                (path => object => path.reduce((o, k) => o[k], object))
                (valuePath.split('.')),
            asc = order === 'ASC' || -1;

        return array.sort((a, b) => 
            const
                aa = getValue(a),
                bb = getValue(b);

            return asc * ((aa > bb) || -(aa < bb));
        );
    ;

var customers = [ Name: "John", Attributes:  Age: 5, Height: 1.5, Country: "USA", Clothes:  Shirts: 5, Pants: 8   ,  Name: "Andrew", Attributes:  Age: 9, Height: 1.8, Country: "Canada", Clothes:  Shirts: 2, Pants: 5   ,  Name: "Lucifer", Attributes:  Age: 11, Height: 1.3, Country: "France", Clothes:  Shirts: 9, Pants: 4   ];


console.log(sort(customers, 'Attributes.Height', 'DESC'));
console.log(sort(customers, 'Attributes.Country', 'DESC'));
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

这是给你的传播问题:***.com/questions/61840455/…

以上是关于对数字和文本的多维对象数组进行排序的主要内容,如果未能解决你的问题,请参考以下文章

php 按最接近数字的值对多维数组进行排序

使用数字键对多维数组进行排序,但保持键相同只是更改顺序

ActionScript 3 在AS3中对多维数组进行排序(数字)

首先按字母顺序对对象数组进行排序,然后按数字排序

对对象的数字数组进行排序[重复]

除数字外,如何按字母顺序对对象数组进行排序?