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 多维数组的排序顺序跨浏览器兼容并与;“自然情况”;_Javascript_Sorting_Multidimensional Array_Cross Browser_Natural Sort - Fatal编程技术网

Javascript 多维数组的排序顺序跨浏览器兼容并与;“自然情况”;

Javascript 多维数组的排序顺序跨浏览器兼容并与;“自然情况”;,javascript,sorting,multidimensional-array,cross-browser,natural-sort,Javascript,Sorting,Multidimensional Array,Cross Browser,Natural Sort,我需要为我的web应用程序复杂地排序一些较大的数组(1000-2000个键)。我在Safari 12.0/FF 66.0中使用了一点,但chrome 74.0似乎完全做了其他事情 我要排序的序列-不区分大小写,使用自然大小写: 1. "scene" 2. "shot" 3. "take" 4. "name" 这些值中的每一个都可以是字符串(例如4、4b或4-PUüöä!)或“未定义”,看起来可能类似于: [ {"scene": "1", "shot": "1", "take"

我需要为我的web应用程序复杂地排序一些较大的数组(1000-2000个键)。我在Safari 12.0/FF 66.0中使用了一点,但chrome 74.0似乎完全做了其他事情

我要排序的序列-不区分大小写,使用自然大小写:

1. "scene"  
2. "shot"  
3. "take"  
4. "name" 
这些值中的每一个都可以是字符串(例如
4
4b
4-PUüöä!
)或“未定义”,看起来可能类似于:

[
  {"scene": "1", "shot": "1", "take": "4", "name": "A031C006_170718_R1W0"},
  {"scene": "8", "shot": "8", "take": "4", "name": "A020C004_170716_R1W0"},
  {"scene": "1", "shot": "1", "take": "10", "name": "A031C013_170718_R1W0"},
  {"scene": undefined, "shot": undefined, "take": undefined, "name": "A001C549_190226_R04Q"},
  {"scene": "2", "shot": "2", "take": "1", "name": "A008C010_170715_R1W0"},
  {"scene": "5", "shot": "5", "take": "1", "name": "A015C005_170716_R1W0"},
  {"scene": "3", "shot": "3", "take": "7", "name": "A002C003_170714_R1W0"},
  {"scene": "5", "shot": "5", "take": "5", "name": "A021C005_170716_R1W0"},
  {"scene": "5", "shot": "5", "take": "9", "name": "A024C006_170717_R1W0"},
  {"scene": "1", "shot": "1", "take": "3", "name": "A004C006_170714_R1W0"},
  {"scene": "1-b", "shot": "1", "take": "3", "name": "A004C007_170718_R1W0*"},
  {"scene": "5", "shot": "5PU", "take": "6", "name": "A021C005_170716_R1W0*"},
]
如果关键点
场景
不存在,请排序到末尾并按“名称”排序

这是vue.js项目的一部分,我希望不用额外的库就能完成

到目前为止,这是我的函数。我使用
localCompare()
4a
4
进行比较。我很确定这非常慢,可以做得更好

sortedFiles = sortClips(files)

sortClips(clips) {
  let firstBy=(function(){function e(f){f.thenBy=t;return f}function t(y,x){x=this;return e(function(a,b){return x(a,b)||y(a,b)})}return e})();

  let options = {
    numeric: true,
    sensitivity: 'base',
    ignorePunctuation: true
  };

  clips.sort(
    firstBy(function (v1, v2) {
      if (!v1.scene) {
        return v1.name.localeCompare(v2.name, undefined, options);
      }
      return v1.scene.localeCompare(v2.scene, undefined, options);
    })
      .thenBy(function (v1, v2) {
        if (!v1.shot) return -1;
        return v1.shot.localeCompare(v2.shot, undefined, options);
      })
      .thenBy(function (v1, v2) {
        if (!v1.take) return -1;
        return v1.take.localeCompare(v2.take, undefined, options);
      })
  );
  return clips;
},
原始数据(场景、快照、拍摄、名称):

Firefox/safari分类:

8 8 4 A020C004_170716_R1W0 
1 1 4 A031C006_170718_R1W0 
1 1 10 A031C013_170718_R1W0 
undefined undefined undefined A001C549_190226_R04Q 
5 5 1 A015C005_170716_R1W0 
5 5 9 A024C006_170717_R1W0 
3 3 7 A002C003_170714_R1W0 
5 5 5 A021C005_170716_R1W0 
1 1 3 A004C006_170714_R1W0 
2 2 1 A008C010_170715_R1W0
1-b 1 3 A004C007_170718_R1W0*
5 5PU 6 A021C005_170716_R1W0*
Chrome的分类不同:

5 5 1 A015C005_170716_R1W0
5 5 9 A024C006_170717_R1W0
3 3 7 A002C003_170714_R1W0
5 5 5 A021C005_170716_R1W0
1 1 3 A004C006_170714_R1W0
undefined undefined undefined "A001C549_190226_R04Q"
8 8 4 A020C004_170716_R1W0
1 1 4 A031C006_170718_R1W0
1 1 10 A031C013_170718_R1W0
2 2 1 A008C010_170715_R1W0
1-b 1 3 A004C007_170718_R1W0*
5 5PU 6 A021C005_170716_R1W0*
目标:

1 1 3 A004C006_170714_R1W0 
1 1 4 A031C006_170718_R1W0 
1 1 10 A031C013_170718_R1W0 
1-b 1 3 A004C007_170718_R1W0*  
2 2 1 A008C010_170715_R1W0
3 3 7 A002C003_170714_R1W0 
5 5 1 A015C005_170716_R1W0 
5 5 5 A021C005_170716_R1W0 
5 5PU 6 A021C005_170716_R1W0*
5 5 9 A024C006_170717_R1W0 
8 8 4 A020C004_170716_R1W0 
undefined undefined undefined A001C549_190226_R04Q 
我怎样才能按我想要的分类呢

更新:
我已经包括了边缘案例:

  • 场景“1-b”当键为“场景”时,添加的字符“-b”应排序在场景“1”的所有元素之后

  • Shot“5PU”当键为“Shot”或“take”时,应忽略添加的字符“PU”


只要比较结果为零,您就可以选择一组键进行排序,然后选择另一个键

var options={numeric:true,sensitivity:'base',ignorepercentration:true},
数组=[{场景:“1”,镜头:“1”,镜头:“4”,namw:“A031C006_170718_R1W0”},{场景:“8”,镜头:“8”,镜头:“4”,名称:“A020C004_170716_R1W0”},{场景:“1”,镜头:“1”,镜头:“10”,名称:“A031C013_170718_R1W0”},{场景:未定义,镜头:未定义,镜头:未定义,镜头:未定义,名称:“A001C549_R04Q”},{场景:“2”,镜头:“2”,镜头:“名称:{A008C010_170715_R1W0“},{场景:“5”,镜头:“5”,镜头:“1”,名字:“A015C005_170716_R1W0”},{场景:“3”,镜头:“3”,镜头:“7”,名字:“A002C003_170714_R1W0”},{场景:“5”,镜头:“5”,名字:“A021C005_170716_R1W0”},{场景:“5”,镜头:“5”,镜头:“9”,名字:“A024C003_170717_R1W0”},镜头:“1”,镜头:“1,{A004C006_170714_R1W0“},{场景:“1-b”,镜头:“1”,镜头:“3”,名字:“A004C007_170718_R1W0*”},{场景:“5”,镜头:“5PU”,镜头:“6”,名字:“A021C005_170716_R1W0*”},
按键=[“场景”、“快照”、“拍摄”、“名称”];
array.sort((a,b)=>{
var结果;
key.some(k=>result=String(a[k]).localeCompare(b[k],未定义,选项));
返回结果;
});
console.log(数组);

。作为控制台包装{max height:100%!important;top:0;}
您的排序函数不稳定

  if (!v1.shot) return -1;

如果
v2
也没有“shot”属性该怎么办?您的排序函数应该总是为
sort(a,b)
sort(b,a)
返回相反的结果,而您的却没有。因为Chrome似乎使用了另一个排序器,它只在这个浏览器中失败(现在,算法可能会在将来发生变化)这是一个复杂的问题。首先是代码,然后是解释:

const场景=[
{“场景”:“1”,“拍摄”:“1”,“拍摄”:“4”,“姓名”:“A031C006_170718_R1W0”},
{“场景”:“8”,“拍摄”:“8”,“拍摄”:“4”,“姓名”:“A020C004_170716_R1W0”},
{“场景”:“1”,“拍摄”:“1”,“拍摄”:“10”,“姓名”:“A031C013_170718_R1W0”},
{“场景”:未定义,“拍摄”:未定义,“拍摄”:未定义,“名称”:“A001C549_190226_R04Q”},
{“场景”:“2”,“拍摄”:“2”,“拍摄”:“1”,“姓名”:“A008C010_170715_R1W0”},
{“场景”:“5”,“拍摄”:“5”,“拍摄”:“1”,“姓名”:“A015C005_170716_R1W0”},
{“场景”:“3”,“拍摄”:“3”,“拍摄”:“7”,“姓名”:“A002C003_170714_R1W0”},
{“场景”:“5”,“拍摄”:“5”,“拍摄”:“5”,“姓名”:“A021C005_170716_R1W0”},
{“场景”:“5”,“拍摄”:“5”,“拍摄”:“9”,“姓名”:“A024C006_170717_R1W0”},
{“场景”:“1”,“拍摄”:“1”,“拍摄”:“3”,“姓名”:“A004C006_170714_R1W0”},
]
常量比较字符串=(a,b)=>{
if(`${a}`!==a)返回1
if(`${b}`!==b)返回-1
返回a.localeCompare(b,未定义{
数字:对,
敏感度:'base',
忽略标点符号:正确
})
}
常量排序=[
“场景”,
"射击",,
“拿”,
“姓名”,
]
常量全局比较=(a,b)=>
排序。减少((acc,键)=>{
如果(acc==0)返回比较器字符串(a[键]、b[键])
返回acc
}, 0)
scenes.sort(globalCompare)

console.log(scenes)
的确如此!感谢您的洞察力,帮助我思考这个案例。这几乎可以完美地工作!谢谢!唯一的问题是,仅定义了“name”的数组元素将位于开头而不是结尾,对吗?是否存在“result”的可能性“是否
null
?我刚刚意识到我遗漏了一些边缘案例。我已经用场景“1-b”更新了我的问题,并拍摄了“5-PU”,它们被排序到数组的末尾。你有什么想法吗?我得到了一个不同的结果
'5PU'
'5'
之后,因为
'5'
较短。这是正确的,但我的用例需要这种排序,在处理键“shot”和“take”时基本上忽略字母:
5 1/5 5 5/5 5PU 6/5 5 9
但使用键“scenes”
a-b
,移动到所有场景的末尾
1
,在场景
2
之前:
1 1 4/1 1 10/1-b 1 3/2 2 1
问题是,您不能(随机)关闭一些字母,因为您需要更多的规则来清理值。谢谢!这也很有效。我接受了Nina Scholz的答案,代码行数减少了:),但我刚刚意识到我遗漏了一些边缘案例。我已经用场景“1-b”更新了我的问题,并拍摄了“5-PU”,它们被排序到数组的末尾。你有什么想法吗?
  if (!v1.shot) return -1;