Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法使用javascript默认排序同时按2个字段排序?_Javascript_Sorting - Fatal编程技术网

无法使用javascript默认排序同时按2个字段排序?

无法使用javascript默认排序同时按2个字段排序?,javascript,sorting,Javascript,Sorting,我尝试按2个字段进行排序,这样,如果字段1不可用,则改为按字段2进行排序 字段1下的代码有效,但字段2无效。显然,默认排序并没有对所有元素进行彻底的比较,只有几个元素。我应该放弃默认排序并构建自己的排序吗 以下是已编辑的jsbin,其中包含当前输出与预期输出: 我将删除旧的代码示例,因为我们有一个更清晰的jsbin。您可以创建一个函数,根据提供的字段属性比较两个对象a、b const data=[{age:0,title:“a”,},{age:5,title:“b”,},{age:“用户未输入

我尝试按2个字段进行排序,这样,如果字段1不可用,则改为按字段2进行排序

字段1下的代码有效,但字段2无效。显然,默认排序并没有对所有元素进行彻底的比较,只有几个元素。我应该放弃默认排序并构建自己的排序吗

以下是已编辑的jsbin,其中包含当前输出与预期输出:


我将删除旧的代码示例,因为我们有一个更清晰的jsbin。

您可以创建一个函数,根据提供的
字段
属性比较两个对象
a、b

const data=[{age:0,title:“a”,},{age:5,title:“b”,},{age:“用户未输入”,title:“fghetwe”,},{age:“奇怪数据”,title:“e”,},{age:5,title:“rtyera”,},{age:“用户未输入”,title:“e”,},{age:1,title:“c”,},{title:“rtyera”,{title:“d”,},{age:2,title:“c”,},{age:null,title:“d”,},{age:[3],title:“c”,},{age:7,title:“c”,},{age:8,title:“a”,},{age:5,title:“h”,},{title:“ayrtyery”,},},{age:1,title:“a”,},{title:“f”,};
//检查值是否为null或未定义
const isNullish=v=>v==null | | typeof v==='undefined'
常量isNullOrNaN=v=>v==null | | isNaN(v)
//根据字段类型发送至comapre 2
功能比较(a、b、字段){
常量aValue=a[field],bValue=b[field];
返回isNullish(bValue)-isNullish(aValue)
||isNullOrNaN(bValue)-isNullOrNaN(aValue)
||(aValue>B值?1:aValue
输入.排序((a,b)=>
比较(a,b,主要排序)|比较(a,b,次要排序)
)
log(customSort(数据,'age','title'))

log(customSort(数据,'title','age'))
请添加一个输入数组样本和两个可选数据字段的预期输出。@adiga那么这不是不可能的吗?我只是想知道这是否是一个完整的解决方案。如果没有看到输入样本、要排序的字段和预期输出,就不清楚您在问什么。预期输出是什么在jsbin中对
数据进行排序后?@adiga ok构建了一个新的示例,其中包含了更多预期的输出。感谢您的回答。不幸的是,字段和值都不在我的控制范围内,我不知道用户将按什么进行排序,以及它们是什么类型。我需要首先检查isNaN,尽管我想我可以在排序之前进行检查?它可能有多种类型,但为了理智起见,我将其限制为数字和字符串。@Harry,您也可以直接检查
字段本身,而不是
比较
如果(字段=='age'|字段=='otherNumberField'){//number logic}中的
字段本身{//string logic}
年龄只是一个例子,它可以是任何东西。例如,它可以是'yearssubscribed',我事先不知道。在比较过程中进行检查似乎对我不太有效。aValue可以是未定义的或字符串,但实际上可能是一个数字。这不起作用:
(isNaN(parseFloat(attr))和&isNaN(parseFloat(bAttr))(!isNaN(attr)和&isNaN(bAttr))
这就是为什么我会遇到这种情况。@Harry我已经更新了。现在它使用了
和三元运算符来比较值。这对字符串和数字有效。这可能会有效。再次感谢你,我编辑了这个示例来打破排序:你能看看这个吗?
var data = [{
  age: 0,
  title: "a",
}, {
  age: 5,
  title: "b",
}, {
  age: "user did not enter",
  title: "fghetwe",
}, {
  age: "strange data",
  title: "e",
}, {
  age: 5,
  title: "rtyera",
}, {
  age: "user did not enter",
  title: "c",
}, {
  age: "user did not enter",
  title: "e",
}, {
  age: 1,
  title: "c",
}, {
  title: "rtyera",
}, {
  age: 1,
  title: "a",
}, {
  title: "d",
}, {
  age: 2,
  title: "c",
}, {
  age: null,
  title: "d",
}, {
  age: [3],
  title: "c",
}, {
  age: 7,
  title: "c",
}, {
  age: 8,
  title: "a",
}, {
  age: 5,
  title: "h",
}, {
  title: "ayrtyery",
}, {
  title: "a",
}, {
  age: 1,
  title: "a",
}, {
    title: "f",
  }]

var primarySort = "age";
var secondarySort = "title"

var list = Backbone.Collection.extend({
  // Reference to this collection's model.
  comparator: function (a, b) {
    let attr = a.get(primarySort)
    let bAttr = b.get(primarySort)

    if (Array.isArray(attr)) attr = attr.join(" ")
    if (Array.isArray(bAttr)) bAttr = bAttr.join(" ")

    if ((isNaN(parseFloat(attr)) && !isNaN(parseFloat(bAttr)))) {
      return -1
    }
    if (!isNaN(parseFloat(attr)) && isNaN(parseFloat(bAttr))) {
      return 1
    }
    if ((!isNaN(attr) && isNaN(bAttr))) {
      return -1
    }
    if ((isNaN(attr) && !isNaN(bAttr))) {
      return 1
    }


    if (attr != null && bAttr != null && !isNaN(parseFloat(attr)) && !isNaN(parseFloat(bAttr))) {
      attr = parseFloat(attr)
      bAttr = parseFloat(bAttr)
      if (attr > bAttr) return 1
      if (attr < bAttr) return -1
      if (attr == bAttr) {
        if (a.get(secondarySort) > b.get(secondarySort)) {
          return 1
        }
        else if (a.get(secondarySort) < b.get(secondarySort)) {
          return -1
        }
      }
    }

    if ((!attr && attr != 0) && (bAttr || bAttr == 0)) {
      return -1
    }

    if ((!bAttr && bAttr != 0) && (attr || attr == 0)) {
      return 1
    }

    if (!attr && attr != 0 && !bAttr && bAttr != 0) {
      if (a.get(secondarySort) > b.get(secondarySort)) {
        return 1
      }
      else if (a.get(secondarySort) < b.get(secondarySort)) {
        return -1
      }

      return 0
    }


    if (isNaN(attr) || isNaN(bAttr)) {
      if (attr > bAttr) return 1
      if (attr < bAttr) return -1
      return 0
    }

    if (a.get(secondarySort) > b.get(secondarySort)) {
      return 1
    }
    else if (a.get(secondarySort) < b.get(secondarySort)) {
      return -1
    }
    else {
      return 0
    }
  },
})


console.log(new list(data).toJSON())
document.getElementById("first").innerHTML += JSON.stringify(new list(data).toJSON(), undefined, 2)

// expected
var firstexpected = [
  {
    "title": "a"
  },
  {
    "title": "ayrtyery"
  },
  {
    "age": null,
    "title": "d"
  },
  {
    "title": "d"
  },
  {
    "title": "f"
  },
  {
    "title": "rtyera"
  },
  {
    "age": "user did not enter",
    "title": "c"
  },
  {
    "age": "strange data",
    "title": "e"
  },
  {
    "age": "user did not enter",
    "title": "e"
  },
  {
    "age": "user did not enter",
    "title": "fghetwe"
  },
  {
    "age": 0,
    "title": "a"
  },
  {
    "age": 1,
    "title": "a"
  },
  {
    "age": 1,
    "title": "a"
  },
  {
    "age": 1,
    "title": "c"
  },
  {
    "age": 2,
    "title": "c"
  },
  {
    "age": [
      3
    ],
    "title": "c"
  },
  {
    "age": 5,
    "title": "b"
  },
  {
    "age": 5,
    "title": "h"
  },
  {
    "age": 5,
    "title": "rtyera"
  },
  {
    "age": 7,
    "title": "c"
  },
  {
    "age": 8,
    "title": "a"
  }
]





primarySort = "title";
secondarySort = "age"

document.getElementById("second").innerHTML += JSON.stringify(new list(data).toJSON(), undefined, 2)

var secondexpected = [
  {
    "title": "a"
  },
  {
    "age": 0,
    "title": "a"
  },
  {
    "age": 1,
    "title": "a"
  },
  {
    "age": 1,
    "title": "a"
  },
  {
    "age": 8,
    "title": "a"
  },
  {
    "title": "ayrtyery"
  },
  {
    "age": 5,
    "title": "b"
  },
  {
    "age": "user did not enter",
    "title": "c"
  },
  {
    "age": 1,
    "title": "c"
  },
  {
    "age": 2,
    "title": "c"
  },
  {
    "age": [
      3
    ],
    "title": "c"
  },
  {
    "age": 7,
    "title": "c"
  },
  {
    "title": "d"
  },
  {
    "age": null,
    "title": "d"
  },
  {
    "age": "strange data",
    "title": "e"
  },
  {
    "age": "user did not enter",
    "title": "e"
  },
  {
    "title": "f"
  },
  {
    "age": "user did not enter",
    "title": "fghetwe"
  },
  {
    "age": 5,
    "title": "h"
  },
  {
    "title": "rtyera"
  },
  {
    "age": 5,
    "title": "rtyera"
  },
]
  {
    "age": "user did not enter",
    "title": "fghetwe"
  },
  {
    "age": "user did not enter",
    "title": "c"
  },
  {
    "age": "user did not enter",
    "title": "e"
  },