在多维数组中对RGB颜色进行排序

时间:2016-03-24 11:45:40

标签: javascript arrays sorting multidimensional-array

我想在此数组中排序(从浅到深)mix颜色代码(组织1024行),但输出还必须包含相应的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>';

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

&#13;
&#13;
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');
&#13;
&#13;
&#13;

答案 2 :(得分:0)

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
})

这种方式的缺点是每个物体都有第4个属性。但是,如果你真的想要,你可以遍历它并删除属性。