JS:按多个字段对数组排序不起作用

时间:2019-07-10 14:02:56

标签: javascript arrays sorting

我想创建按此顺序对元素进行排序的方法:

    列表上的
  1. 1st必须是“活动的”元素(isActive字段设置为true)。如果两个比较元素都处于活动状态,则按字母顺序排序。

  2. 列表中的下一个元素是必须将字段(createSheet和centralBox)设置为true的这些元素。如果两个比较的元素都将此字段设置为true,则按字母顺序排序。

  3. 列表中的下一个元素是仅将centralBox字段设置为true的元素。与所有其他情况一样,当两个元素都将这些字段设置为true时,然后按字母顺序排序。

  4. 列表中的下一个元素是仅将createSheet字段设置为true的元素。和上面一样...

  5. 层次结构中的最后排序是按字母顺序排序

这是我制作的,它不起作用(名称是字符串,其他文件是布尔值):

    sortingSelectList = (firstElement, secondElement) => {
    const elementToCompare = {
        name: firstElement.label.toLowerCase(),
        isActive: this.state.activeSystems.ids.includes(firstElement.label),
        createSheet: this.state.systems.entities[firstElement.label].createSheet,
        centralBox: this.state.systems.entities[firstElement.label].centralBox
    };
    const comparingElement = {
        name: secondElement.label.toLowerCase(),
        isActive: this.state.activeSystems.ids.includes(secondElement.label),
        createSheet: this.state.systems.entities[secondElement.label].createSheet,
        centralBox: this.state.systems.entities[secondElement.label].centralBox
    };

    if (elementToCompare.isActive < comparingElement.isActive) { return -1; }
    if (elementToCompare.isActive > comparingElement.isActive) { return 1; }

    if (elementToCompare.centralBox && elementToCompare.createSheet < comparingElement.centralBox && comparingElement.createSheet) { return -1; }
    if (elementToCompare.centralBox && elementToCompare.createSheet > comparingElement.centralBox && comparingElement.createSheet) { return 1; }

    if (elementToCompare.centralBox < comparingElement.centralBox) { return -1; }
    if (elementToCompare.centralBox > comparingElement.centralBox) { return 1; }

    if (elementToCompare.createSheet < comparingElement.createSheet) { return -1; }
    if (elementToCompare.createSheet > comparingElement.createSheet) { return 1; }

    if (elementToCompare.name < comparingElement.name) { return -1; }
    if (elementToCompare.name > comparingElement.name) { return 1; }

    return 0;
}

有人可以帮我吗?

示例:

Object 1: { name: B,
        isActive: true,
        createSheet: false,
        centralBox: false }
Object 2: { name: A,
        isActive: true,
        createSheet: false,
        centralBox: false }         
Object 3: { name: B,
        isActive: false,
        createSheet: false,
        centralBox: false }
Object 4: { name: B,
        isActive: false,
        createSheet: false,
        centralBox: true }
Object 5: { name: B,
        isActive: false,
        createSheet: true,
        centralBox: false }
Object 6: { name: B,
        isActive: false,
        createSheet: true,
        centralBox: true }

预期顺序:对象2->对象1->对象6->对象4->对象5->对象3

4 个答案:

答案 0 :(得分:1)

一种方法可能是根据您的条件对对象进行编码和加权。看一下这段代码:

var obj = [
{ name: "B",
  isActive: true,
  createSheet: false,
  centralBox: false },
{ name: "A",
  isActive: true,
  createSheet: false,
  centralBox: false },
{ name: "B",
  isActive: false,
  createSheet: false,
  centralBox: false },
{ name: "B",
  isActive: false,
  createSheet: false,
  centralBox: true },
{ name: "B",
  isActive: false,
  createSheet: true,
  centralBox: false },
{ name: "B",
  isActive: false,
  createSheet: true,
  centralBox: true }
]

for (const o of obj){
  let score = o.isActive === true ? 0 : 50
  score += o.centralBox === true ? 0 : 20
  score += o.createSheet === true ? 0 : 10
  score += o.name.charCodeAt(0)
  o.score = score
}
obj.sort((a, b) => a.score - b.score)
console.log(obj)

答案 1 :(得分:0)

比较的优先级高于&&,因此请尝试更改

(elementToCompare.centralBox && elementToCompare.createSheet < comparingElement.centralBox && comparingElement.createSheet)

((elementToCompare.centralBox && elementToCompare.createSheet) < (comparingElement.centralBox && comparingElement.createSheet))

即将要比较的内容括在括号中。

答案 2 :(得分:0)

您需要一个单独的对象来保存所需的排序顺序。我过去使用过以下代码,不是我自己的,但不记得我在哪里得到的,所以不能给功劳。

正方向表示升序排列,负方向则相反

MethodChannel

然后,您需要遍历上面的每个属性,并将每个属性应用于数组:

let sortBy = [{
  prop:'isActive',
  direction: 1
},{
  prop:'createSheet',
  direction: 1
},
{
  prop:'centralBox',
  direction: 1
},
{
  prop:'name',
  direction:1
}];

array.sort(function(a,b){ let i = 0, result = 0; while(i < sortBy.length && result === 0) { 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)); i++; } return result; }) 转换使代码更加灵活,因此可以应用于多种排序情况。

我们还会乘以您要求的方向。

将其应用于您的数组将得到:

enter image description here

答案 3 :(得分:-1)

您有很多不同的条件。 Sou为每个条件存储过滤结果。检查filter功能。 最后,将所有阵列合并到一个阵列中。检查concat功能。