Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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 如何使用DOM方法可靠地进行亚RT数组?_Javascript_Arrays_Dom_Sorting - Fatal编程技术网

Javascript 如何使用DOM方法可靠地进行亚RT数组?

Javascript 如何使用DOM方法可靠地进行亚RT数组?,javascript,arrays,dom,sorting,Javascript,Arrays,Dom,Sorting,预先说明:我没有在这里使用jQuery或其他库,因为我想了解我写了什么以及为什么它可以(或不能)工作,所以请不要用库或库插件来回答这个问题。我并不反对库,但对于这个项目,它们不利于我的编程目标 也就是说 最后,我使用自己编写的DOM函数添加了一些列排序。问题是,虽然它对(比如)简单的字母排序字符串非常有效,但当我尝试对多个数字项进行排序时,结果在不同浏览器中是不一致的,实际上,当我尝试对两个子项进行排序时 例如,如果您在Safari或OS X上的Firefox中单击“十进制RGB”几次,就会得到

预先说明:我没有在这里使用jQuery或其他库,因为我想了解我写了什么以及为什么它可以(或不能)工作,所以请不要用库或库插件来回答这个问题。我并不反对库,但对于这个项目,它们不利于我的编程目标

也就是说

最后,我使用自己编写的DOM函数添加了一些列排序。问题是,虽然它对(比如)简单的字母排序字符串非常有效,但当我尝试对多个数字项进行排序时,结果在不同浏览器中是不一致的,实际上,当我尝试对两个子项进行排序时

例如,如果您在Safari或OS X上的Firefox中单击“十进制RGB”几次,就会得到我想要的结果。在Chrome或Opera(同样是OSX)中执行同样的操作,会得到非常不同的结果。是的,狩猎和铬在这里是不同的

下面是我用于RGB排序的JS的一个片段:

sorter.sort(function(a,b){
    return a.blue - b.blue;
});
sorter.sort(function(a,b){
    return a.green - b.green;
});
sorter.sort(function(a,b){
    return a.red - b.red;
});
sorter
是我试图排序的数组。)

按照另一个StackOverflow问题“”和“”的传统进行排序。然而,在我最初试用的四款浏览器中,有两款的结果并不是我所期望的

我有点(哈!)觉得这与数组排序“不稳定”有关——这里没有参数-但我不知道的是如何以一致、可靠的方式克服它。我真的需要一些帮助来理解问题和看到解决方案,或者至少是对解决方案的一般描述

我意识到可能有600万种方法可以优化JS的其余部分(是的,我使用了全局优化)。我仍然是一个JS新手,并试图通过实践来纠正这一点。现在,让我感到困惑的是数组排序,在继续清理其他地方的代码之前,我可以在这段脚本中使用一些帮助。提前谢谢

更新

除了下面的精彩解释和建议外,我还得到了一个更加紧凑的解决方案:

function rgbSort(a,b) {
    return (a.red - b.red || a.green - b.green || a.blue - b.blue);
}

尽管我还不太了解它,但我想我已经开始掌握它的轮廓,这就是我现在正在使用的东西。谢谢大家的帮助

好的。因此,正如您所发现的,您的问题是默认JavaScript排序不能保证稳定。具体地说,我认为在你看来,它是这样工作的:我将按蓝色排序,然后当我按绿色排序时,排序器只会上下移动数组中的条目,但按蓝色排序。可悲的是,宇宙的安排并不那么方便;内置的JS排序可以按自己喜欢的方式进行排序。特别是,它允许将数组的内容扔进一个大桶中,然后按您要求的内容进行排序,完全忽略它以前是如何排列的,看起来至少有些浏览器正是这样做的

对于您的特定示例,有几种方法可以解决此问题。首先,您仍然可以在三个单独的调用中进行排序,但请确保这些调用稳定地进行排序:这意味着在按蓝色排序之后,您将稳定地按绿色排序,这将为您提供一个按绿色排序的数组,并在该数组中按蓝色顺序排序(即,正是您要查找的)。我的sorttable库通过实现“shaker排序”或“鸡尾酒排序”方法来实现这一点(http://en.wikipedia.org/wiki/Cocktail_sort); 本质上,这种排序方式会在列表中进行多次遍历,并上下移动项目。(特别是,它没有做的只是将所有列表项扔进一个桶中,然后按顺序将它们取出。)维基百科文章上有一个漂亮的小图片。这意味着“subsorts”保持排序,即排序是稳定的,这将为您提供所需的内容

然而,对于这个用例,我不会担心在三个不同的调用中进行排序,并确保它们是稳定的等等;相反,我会一次完成所有的排序。我们可以把rgb颜色指示器(25519280)想象成一个奇怪基数的大数字:为了避免过多的数学运算,假设它在基数1000中(如果这个短语没有意义,忽略它;只需将整个rgb属性转换为一个包含所有属性的数字,有点像CSS在级联中计算先例的方式)因此,这个数字实际上可以被认为是255192080。如果你为每一行计算这个数字,然后按这个数字排序,那么一切都会解决,你只需要做一次排序:因此,你可以做一次:
sorter.sort(函数(a,b){return(a.red*1000000+a.green*1000+a.blue)-(b.red*1000000+b.green*1000+b.blue)}
一切都会解决的


从技术上讲,这有点低效,因为每次调用排序函数时都必须计算“基数1000”,这可能(很可能)是每行不止一次。如果这是一个大问题(可以通过基准测试来解决),那么可以使用Schwartzian变换(抱歉这里有这么多流行语):基本上,您只需计算每行的基数1000,将它们全部放入一个列表中,对列表进行排序,然后遍历排序后的列表。因此,创建一个类似于
[[255192080]、[255255255]、[192000000]
的列表,对该列表进行排序(使用类似于
mylist.sort(函数(a,b){return a[0]-b[0];})
),然后浏览该列表并将每个附加到表中,这将按顺序对整个表进行排序。您可能不需要将最后一段添加到您拥有的表中,但了解sorttable.js也使用的这个技巧可能会很有用,当然也不会有什么坏处。

我将以不同的方式处理此问题似乎您正试图通过从标记中提取数据来重建所有数据,这可能是一项危险的任务
var colorsData = [
  {
    keyword: 'mediumspringgreen',
    decimalrgb: {
      r: 0,
      g: 250,
      b: 154
    },
    percentrgb: {
      r: 0,
      g: 98,
      b: 60.4
    },
    hsl: {
      h: 157,
      s: 100,
      l: 49
    }
    hex: '00FA9A',
    shorthex: undefined
  },
  {
    //next color...
  }
];
var decimalRgbForwards = function(a,b) {
  var a = a.decimalrgb,
      b = b.decimalrgb;
  if ( a.r === b.r ) {
    if ( a.g === b.g ) {
      return a.b - b.b;
    } else {
      return a.g - b.g;
    }
  } else {
    return a.r - b.r;
  }
};
colorsData.sort(decimalRgbForwards);