Sorting an array to avoid neighboring items having

2019-07-13 17:34发布

问题:

I have an array of objects. Each object has a color attribute which could be "red", "blue", "yellow", "green", "orange" or "purple". There are 20-30 objects in the array so colors repeat. My goal is to sort the array so that no colors are next to each other. Distribution of colors is not exactly even but close.

This is what I have so far. It checks the next and previous object for a color match and if it finds a match it moves it to the end of the array.

private function sortColors():void
{
    var getNext:uint;
    var getPrev:uint;
    var maxCount:uint = colorArray.length;
    for (var i:uint = 0; i < maxCount; i++) {
        var cur:ValueObject = colorArray[i];
        (i == maxCount-1) ? getNext = 0 : getNext = i+1;
        (i == 0) ? getPrev = maxCount-1 : getPrev = i-1;
        var next:ValueObject = colorArray[getNext];
        var prev:ValueObject = colorArray[getPrev];
        if (cur.color == next.color) {
            var move:ValueObject = colorArray[getNext];
            colorArray.splice(getNext, 1);
            colorArray.push(move);
        }
        if (cur.color == prev.color) {
            var move:ValueObject = colorArray[getPrev];
            colorArray.splice(getPrev, 1);
            colorArray.push(move);
        }
    }
}

This works OK but if there is more of a certain color they end up repeating at the end. I could add something to the end to throw those back into the mix but I feel like there must be a better way. Someone enlighten me.

回答1:

Try:

var colorObjects:Array = [/* list of objects with colors - populated below*/];
var jumbled:Array = [];

var lastColor:String = "";
function getDifferentTile():void
{
    if(lastColor.length == 0)
    {
        jumbled.push(colorObjects.pop());
        lastColor = jumbled[0].mycolor;
    }
    else
    {
        var i:Object;
        for each(i in colorObjects)
        {
            var repeat:uint = 0;
            if(i.mycolor != lastColor)
            {
                jumbled.push(i);
                lastColor = i.mycolor;

                colorObjects.splice(colorObjects.indexOf(i), 1);

                return;
            } else {
               repeat++;
            }
            if (repeat > 0 && repeat == colorObjects.length) {
               jumbled.push(i);
               colorObjects.splice(colorObjects.indexOf(i), 1);
               return;
            }
        }
    }
}

// list of random colors
var colors:Array = ["0x000000","0x444444","0xFFFFFF","0xFF00FF"];

// prepare random array for test
var i:uint = 0;
for(i; i<100; i++)
{
    var obj:Object =
    {
        mycolor: colors[uint(Math.random()*colors.length)]
    };

    colorObjects.push(obj);
}


// fill the jumble array until the original listing is empty
while(colorObjects.length > 0)
{
    getDifferentTile();
}


// output jumbled
var j:Object;
for each(j in jumbled)
{
    trace(j.mycolor);
}