【问题标题】:Sort RGB color in multidimensional array在多维数组中对 RGB 颜色进行排序
【发布时间】:2016-03-24 11:45:39
【问题描述】:

我想对这个数组(org. 1024 行)中的mix 颜色代码进行排序(从浅到深),但输出还必须包含相应的 c1 和 c2 颜色代码以供以后使用。

 var colors = [
{ c1: 'rgb(255,255,255)', c2: 'rgb(255,249,225)', mix: 'rgb(255,252,240)' },
{ c1: 'rgb(255,255,255)', c2: 'rgb(205,205,205)', mix: 'rgb(230,230,230)' },
{ c1: 'rgb(255,255,255)', c2: 'rgb(171,163,144)', mix: 'rgb(213,209,199)' },
{ c1: 'rgb(255,255,255)', c2: 'rgb(28,28,28)', mix: 'rgb(141,141,141)' },
{ c1: 'rgb(255,255,255)', c2: 'rgb(97,9,17)', mix: 'rgb(176,132,136)' },
{ c1: 'rgb(255,255,255)', c2: 'rgb(170,11,39)', mix: 'rgb(212,133,147)' },
{ c1: 'rgb(255,255,255)', c2: 'rgb(206,116,108)', mix: 'rgb(230,185,181)' },
{ c1: 'rgb(255,255,255)', c2: 'rgb(243,218,221)', mix: 'rgb(249,236,238)' }
];

我试图调整this example code,但不知道如何得到我想要的。首选输出可以是与上面相同的数组结构,因此我可以复制/粘贴它以供进一步使用。

有人能想出一个可能的解决方案吗?

更新: John Slegers 用这段代码给了我最好的解决方案(从亮到暗都很漂亮):

colors.sort(function(a, b) {
    var calculateLuminosity = function(rgb) {
        return rgb.replace(/[^[\d,]/g, "")
                  .split(",")
                  .map(Number)
                  .reduce(function(pv, cv) { return pv + cv; }, 0);
    }
    var luminosity = {
        a : calculateLuminosity(a.mix),
        b : calculateLuminosity(b.mix),
    }
    if (luminosity.a === luminosity.b) {
        return 0;
    } else {
        return (luminosity.a > luminosity.b) ? -1 : 1;
    }
});

document.body.innerHTML = '<pre>' + JSON.stringify(colors, null, '\t') + '</pre>';

【问题讨论】:

  • 您能否在问题中添加预期的输出?
  • 对不起,我会调整问题...

标签: javascript arrays sorting multidimensional-array


【解决方案1】:

应该这样做:

colors.sort(function(a, b) {
    var calculateLuminosity = function(rgb) {
        return rgb.replace(/[^[\d,]/g, "")
                  .split(",")
                  .map(Number)
                  .reduce(function(pv, cv) { return pv + cv; }, 0);
    };

    var luminosity = {
        a : calculateLuminosity(a.mix),
        b : calculateLuminosity(b.mix),
    };

    if (luminosity.a === luminosity.b) {
        return 0;
    } else {
        return (luminosity.a > luminosity.b) ? -1 : 1;
    }
});

演示

var colors = [
    { c1: 'rgb(255,255,255)', c2: 'rgb(255,249,225)', mix: 'rgb(255,252,240)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(205,205,205)', mix: 'rgb(230,230,230)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(171,163,144)', mix: 'rgb(213,209,199)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(28,28,28)', mix: 'rgb(141,141,141)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(97,9,17)', mix: 'rgb(176,132,136)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(170,11,39)', mix: 'rgb(212,133,147)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(206,116,108)', mix: 'rgb(230,185,181)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(243,218,221)', mix: 'rgb(249,236,238)' }
];

colors.sort(function(a, b) {
    var calculateLuminosity = function(rgb) {
        return rgb.replace(/[^[\d,]/g, "")
                  .split(",")
                  .map(Number)
                  .reduce(function(pv, cv) { return pv + cv; }, 0);
    };

    var luminosity = {
        a : calculateLuminosity(a.mix),
        b : calculateLuminosity(b.mix),
    };

    if (luminosity.a === luminosity.b) {
        return 0;
    } else {
        return (luminosity.a > luminosity.b) ? -1 : 1;
    }
});

document.body.innerHTML = '<pre>' + JSON.stringify(colors, null, '\t') + '</pre>';

(另见this Fiddle

【讨论】:

  • 我在 1024 行数组上尝试了您的第一个代码,它给出了从浅到深的结果,非常漂亮。您调整后的代码给出了混合,浅色,深色,浅色,深色,深色。所以,我先用你的,在你调整之前,谢谢你的帮助。
  • @Harry:太好了!根据您的反馈,我再次更新了答案:-)
  • 不不,这是在这个之后和你最新之前的代码。
  • @Harry : 这个版本?!
  • 我将使用我的意思的代码更新我的问题,以便您可以更新您对我投票的答案。 (zag net dat je in de buurt woont :-))
【解决方案2】:

for 循环将分解 rgb,并使用前面的链接计算 RGB 的亮度。我已将其作为属性添加到对象中。

for (var i=0; i<colors.length; i++) {
  var rgb = colors[i].mix.match(/\d{3}/g)
  colors[i].brightness = 0.2126*rgb[0] + 0.7152*rgb[1] + 0.0722*rgb[2]
}

然后这种排序方法会根据亮度对数组中的对象重新排序。

colors.sort(function(a, b) {
  return a.brightness - b.brightness
})

这种方式的缺点是每个对象都有第四个属性。但是,如果您真的想要,您可以遍历它并删除属性。

【讨论】:

    【解决方案3】:

    referenced answer 稍作修改(并更正排序回调函数):

    function luminance(str) {
      // extract digits groups from strings like "rgb(255,255,255)"
      // and split into numbers:
      var rgb = str.match(/\d+/g).map(Number);
      return 0.2126*rgb[0] + 0.7152*rgb[1] + 0.0722*rgb[2];
    }
    
    var colors = [
    { c1: 'rgb(255,255,255)', c2: 'rgb(255,249,225)', mix: 'rgb(255,252,240)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(205,205,205)', mix: 'rgb(230,230,230)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(171,163,144)', mix: 'rgb(213,209,199)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(28,28,28)', mix: 'rgb(141,141,141)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(97,9,17)', mix: 'rgb(176,132,136)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(170,11,39)', mix: 'rgb(212,133,147)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(206,116,108)', mix: 'rgb(230,185,181)' },
    { c1: 'rgb(255,255,255)', c2: 'rgb(243,218,221)', mix: 'rgb(249,236,238)' }
    ];
    
    colors.sort(function (a, b) {
      // this function expects an integer value, so subtract:
      return luminance(b.mix) - luminance(a.mix);
    });
    
    // Just for this snippet: display the result in readable form:
    document.body.innerHTML = '<pre>' + JSON.stringify(colors). replace(/},/g, '},\n');

    【讨论】:

      猜你喜欢
      • 2015-03-13
      • 2015-12-29
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 2017-11-09
      • 2023-03-23
      相关资源
      最近更新 更多