Question

I have a nice riddle that I would like to see solved. There might be a better way of doing this and i am open for idea's. I am trying to write an undo function for a canvas drawing app. I have the following object, within it an array with their own objects with three properties.

var allDamages= {};
allDamages['scratch'] = [];
allDamages['scratch'].push({"x":4,"y":6,"index":1});
allDamages['scratch'].push({"x":3,"y":3,"index":2});
allDamages['scratch'].push({"x":9,"y":9,"index":3});
allDamages['scratch'].push({"x":19,"y":39,"index":4});
allDamages['dent'] = [];
allDamages['dent'].push({"x":59,"y":69,"index":5});
allDamages['dent'].push({"x":59,"y":69,"index":9});
allDamages['dent'].push({"x":39,"y":19,"index":6});
allDamages['rip'] = [];
allDamages['rip'].push({"x":20,"y":22,"index":7});
allDamages['rip'].push({"x":100,"y":56,"index":8});

I want to remove the last entry from this array. I want to do this by the property 'index'. So I need to somehow find the entry which has the highest value of the property 'index' and then remove it from the array. What is the best way in doing this?

Greetings,

Robert

Was it helpful?

Solution

allDamages.scratch.length -1 returns the last index for that array.

Edit:

allDamages.scratch.slice(-1).pop() returns the last array item.

And if you just want to remove the last item in your array you should (like Givi said) use the pop() method on a sorted array like so:

allDamages['scratch'].pop()

Edit2:

Because the question wasn't clear for me. This is my final shot at the problem.

var allDamagesInOneArray = [];

for(array in allDamages){
    allDamagesInOneArray.concat(array);//Assuming every key is an array
}

allDamagesInOneArray.sort(function(a,b){
    return a.index - b.index;
});

var lastObj = allDamagesInOneArray.slice(-1).pop(); //element with latest index

OTHER TIPS

I think you should create an object that save three your properties. After that you create a stack for undo. Like this:

function yourObject(x,y,index){
   this.x = x; this.y = y; this.index = index;    
}

var yourStack = new Array();

yourStack.push(new yourObject(4, 6, 1));

If the highest index in an array is always the last element of the array:

allDamages.scratch = allDamages.scratch.slice(0, allDamages.scratch.length - 1);

This removes the last element of the array

If index is not incrementing or if you always want to remove the latest index, no matter in which of the damages arrays it is (as I'd guess) you can use this function:

var undo = function(input){

    var max= 0;
    var undoType = "";
    var undoIndex = 0;
    for( var type in input ) {
        // type: string

        var locations = input[type];
        // locations: array

        // find the location of the heighest index property.
        for( var i = 0; i < locations.length; i++ ) {
            if( locations[i]["index"] > max) {
                max = locations[i]["index"] ;
                undoType = type;
                undoIndex = index;
            }
        }
    }

    var output = input[type].splice(undoIndex, 1);
    return output;
}

This should remove the element with the largest "index" property from your damage array.

First off, store a counter for highest index property found in the objects, and the index of that object within the scratch array.

var highestIndex = -Infinity;
var indexInArray

Then if you're using jQuery:

$.each( allDamages.scratch, function highestIndex( index, object ){
  if( object.index > highestIndex ){
    highestIndex = object.index;
    indexInArray = index;
  }
} );

Or, if not:

for( var indexCounter = 0, indexCounter < allDamages.scratch, indexCounter++ ){
  if( allDamanges.scratch[ indexCounter ].index > highestIndex ){
    highestIndex = allDamages.scratch[ indexCounter ].index;
    indexInArray = indexCounter;
  }
};

Try:

var allDamages= {};
allDamages['scratch'] = [];
allDamages['scratch'].push({"x":4,"y":6,"index":1});
allDamages['scratch'].push({"x":3,"y":3,"index":2});
allDamages['scratch'].push({"x":9,"y":9,"index":3});
allDamages['scratch'].push({"x":19,"y":39,"index":4});
allDamages['dent'] = [];
allDamages['dent'].push({"x":59,"y":69,"index":5});
allDamages['dent'].push({"x":59,"y":69,"index":9});
allDamages['dent'].push({"x":39,"y":19,"index":6});
allDamages['rip'] = [];
allDamages['rip'].push({"x":20,"y":22,"index":7});
allDamages['rip'].push({"x":100,"y":56,"index":8});
var index;
var cnt = 0;
var val;
$.each(allDamages,function(k,v){        
    if(cnt == 0){
        index = highest(v);  //get highest value from each object of allDamages    
        val = k;
    }
    else{
        if(highest(v) > index){
            index = highest(v);
            val = k;
        }
    }
    cnt++;    
});
console.log("highest : "+index+": "+val);
var len = allDamages[val].length;
for(var i=0;i<len;i++){    
    if(allDamages[val][i].index == index){
        allDamages[val].splice(i,1); //remove object having highest value
        break;
    }
}
console.log(allDamages);
function highest(ary) {
    var high = ary[0].index;
    var len = ary.length;
    if(len > 0){
        for(var i=0;i<len;i++){
            if(ary[i].index > high){
                high = ary[i].index;
            }
        }
    }
    return high;
}

DEMO here.

I've simplified my array to:

allDamages.push({"x":39,"y":19,"index":6,"type":'dent'});

That way i can use .pop() function in a normal way.

Thank you all for the quick response!!!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top