对数字和文本的多维对象阵列进行排序。

问题描述 投票:0回答:3
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)

我该如何进行必要的修改?谢谢你的时间。

javascript jquery arrays object multidimensional-array
3个回答
1
投票

字符串排序的工作方式不同,读作 此处. 我们的想法是首先检测你要应用排序的键的类型是数字还是字符串,然后应用相应的排序。

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));

1
投票

与其使用减号运算符进行数学比较,不如直接用 <> 操作符。这对数字和字符串都适用。

  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.orgen-USdocsWebJavaScriptReferenceGlobal_ObjectsArraysort#描述。


1
投票

你可以采用一个对数字和字符进行排序的方法,在路径和排序顺序上使用闭包。

这种方法通过将数组作为第一参数来改变参数的顺序。

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; }
© www.soinside.com 2019 - 2024. All rights reserved.