如何使用键和排序顺序在嵌套数组上实现排序

时间:2019-06-18 08:35:58

标签: javascript arrays sorting

我正在尝试根据键和排序顺序对嵌套数组进行多种排序。

我能够根据键和顺序对数组进行排序

我已经完成以下代码对数组进行排序

return array.sort((a, b) => {
      let i = 0, result = 0;
      while (i < sortBy.length && result === 0) {
        if (typeof a[sortBy[i].prop] == "string") {
          result = sortBy[i].direction * (a[sortBy[i].prop].toString() < b[sortBy[i].prop].toString() ? -1 : (a[sortBy[i].prop].toString() > b[sortBy[i].prop].toString() ? 1 : 0));
        } else {
          result = sortBy[i].direction * (a[sortBy[i].prop] < b[sortBy[i].prop] ? -1 : (a[sortBy[i].prop] > b[sortBy[i].prop] ? 1 : 0));
        }
        i++;
      }
      return result;
    });

我的输入数据如下,

array = [{ x: [{ d: 4 }, { d: 2 }, { d: 3 }, { d: 1 }], b: 'v' }, { x: [{ d: 8 }, { d: 7 }, { d: 5 }, { d: 6 }], b: 's' }];
sortBy= [{ 'prop': 'b', 'direction': 1 }, { 'prop': 'd', 'direction': 1}];

我希望得到如下输出,

array = [{ x: [{ d: 5 }, { d: 6 }, { d: 7 }, { d: 8 }], b: 's' },{ x: [{ d: 1 }, { d: 2 }, { d: 3 }, { d: 4 }], b: 'v' }];

但是我得到以下结果,

array = [{ x: [{ d: 8 }, { d: 7 }, { d: 5 }, { d: 6 }], b: 's' },{ x: [{ d: 4 }, { d: 2 }, { d: 3 }, { d: 1 }], b: 'v' }];

我坚持如何解决这个逻辑问题。有人可以帮我吗?

2 个答案:

答案 0 :(得分:1)

您接近了,您要做的是在具有属性x的内部数组上调用sort方法。然后后记在原始数组上调用它。这将首先使用d属性对子数组进行排序,然后对后数组按b进行排序。

array = [{ x: [{ d: 4 }, { d: 2 }, { d: 3 }, { d: 1 }], b: 'v' }, { x: [{ d: 8 }, { d: 7 }, { d: 5 }, { d: 6 }], b: 's' }];
sortBy= [{ 'prop': 'b', 'direction': 1 }, { 'prop': 'd', 'direction': 1}];

function sortFunc(a, b) {
  let i = 0, result = 0;
  while (i < sortBy.length && result === 0) {
    if (typeof a[sortBy[i].prop] == "string") {
      result = sortBy[i].direction * (a[sortBy[i].prop].toString() < b[sortBy[i].prop].toString() ? -1 : (a[sortBy[i].prop].toString() > b[sortBy[i].prop].toString() ? 1 : 0));
    } else {
      result = sortBy[i].direction * (a[sortBy[i].prop] < b[sortBy[i].prop] ? -1 : (a[sortBy[i].prop] > b[sortBy[i].prop] ? 1 : 0));
    }
    i++;
  }
  return result;
}

array.forEach(arr => arr.x = arr.x.sort(sortFunc));
array = array.sort(sortFunc);
console.log(array);
    

答案 1 :(得分:1)

据我所见,您需要递归调用此函数,并在您击中对象中的数组时调用该函数。看看这个

let input = [
{ x: [{ d: 4 }, { d: 2 }, { d: 3 }, { d: 1 }], b: 'v' }, 
{ x: [{ d: 8 }, { d: 7 }, { d: 5 }, { d: 6 }], b: 's' }
];

const sortingInstructions = [
  {prop: 'b', direction: 1},
  {prop: 'd', direction: 1}
];

const isArray = Obj => {
  return typeof(Obj) === 'object' && Obj.length !== undefined
}

const nestedSort = SortingArray => {
  for(let obj of SortingArray){
  	for(let key of Object.keys(obj)){
    	if(isArray(obj[key])){
        nestedSort(obj[key])
      }
    }  	
  }
  for(let instruction of sortingInstructions){

    SortingArray.sort((a,b) => {
      if(typeof(a[instruction.prop]) === 'string'){
        return instruction.direction*b[instruction.prop].localeCompare(a[instruction.prop])
      }
      if(typeof(a[instruction.prop]) === 'number'){
        return instruction.direction*(b[instruction.prop]-a[instruction.prop]);
      }
    })
  }
	
  
  return SortingArray;
}

nestedSort(input);
console.log(input);

它的作用如下。

  1. 如果在对象中命中一个数组,则在该数组上递归调用该函数

  2. 您可以按照所有指令对数组进行排序(指令中位于最下方的将优先选择占主导地位的数组,因为它们用于对最新数组进行排序)

  3. 如果您输入的是字符串,则可以使用localeCompare对其进行排序

由于这是递归的,因此也可以在任何深度的对象上运行。例如

let input = [
  { x: [{y:[{ d: 4 }, { d: 2 }, { d: 3 }, { d: 1 }]}], b: 'v' }, 
  { x: [{z:[{ d: 8 }, { d: 7 }, { d: 5 }, { d: 6 }]}], b: 's' }
]

也可以