【问题标题】:How to implement sorting on nested array with keys and sorting order如何使用键和排序顺序对嵌套数组进行排序
【发布时间】:2019-06-18 08:35:58
【问题描述】:

我正在尝试基于键和排序顺序对嵌套数组实现多重排序。

我可以根据键和顺序对数组进行排序

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

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' }];

我不知道如何解决这个逻辑问题。谁能帮我解决这个问题。

【问题讨论】:

  • 您的“逻辑”问题是您不想对一个数组进行排序,而是以两种不同的方式(通过不同的属性)对三个数组进行排序。
  • 是你的数组的结构总是这样。或者是否会发生属性 d 像这样隐藏的输入 = [{x: [{b: [{d: 1}]}]}];
  • 是的@Thomas。我需要先根据属性“b”按升序对数组进行排序,然后按升序对数组“x”上的属性“d”进行排序。
  • 你从哪里知道,x 是下一个要排序的属性?
  • @relief.melone 结构有时会发生变化,例如输入 = [{b:'',x:[]}]。但是不会有隐藏的情况 input = [{x: [{b: [{d: 1}]}]}];

标签: javascript arrays sorting


【解决方案1】:

您已经接近了,您要做的是在具有属性x 的内部数组上调用您的排序方法。然后在原始数组上调用它。这将首先使用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);
    

【讨论】:

    【解决方案2】:

    据我所知,您需要将其设为递归,并在遇到对象中的数组时调用该函数。看看这个

    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' }
    ]
    

    也可以

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多