3

I am trying to remove some elements from an array, and use the splice functionality where it also returns those values. See the javascript below:

var blocksUsed = allNumbers.splice(0,3);

When trying to run this line (in conjunction with the entire function), I get an error saying the following:

Uncaught TypeError: undefined is not a function

I have spent quite some time looking for typographical errors in the function, but there don't seem to be any. I also ready that JQuery is the common troublemaker here, but I am not using JQuery.

The array is created by shuffling another array (the shuffle function isn't mine):

function shuffle(o){
    for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};

Which I then use in the following manner:

var allNumbers = shuffle(blocks);

I tried logging the allNumbers, which works correctly. The array gets shuffled correctly. Trying to do a splice on this however gives a same error.

Also note that I am doing the splicing inside a for-loop. Code below.

for (var i = 0; i < 4; i++){

    // Get a block of 3 blocks.
    var blocksUsed = allNumbers.splice(0,3); // This line gives the error.

    // Determine the color used for these blocks and remove it so that it doesn't get drawn again.
    var colorIndex = randomIntFromInterval(0,i);
    var colorUsed = otherColors[colorIndex];
    if(otherColors.indexOf(colorUsed) > -1){
        otherColors.splice(colorIndex, 1);
    }

    // For each block, set the color.
    for(var j = 0; j < 3; j++){
        blocksUsed[j].className = "block " + colorUsed;
    }
}

Why can I not use splice on this array? Note that I can provide the entire function, if desired. I have the entire function at this codepen for reference straight away.

Because of the comment:

allNumbers is a shuffled version of an array containing elements received in the following manner:

var blocks = document.getElementsByClassName('block');
3
  • It is an array of div-elements. Commented Dec 9, 2014 at 16:14
  • 2
    blocks isn't an array, it's a NodeList. So is allNumbers. Commented Dec 9, 2014 at 16:17
  • for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); is the nastiest line of code I've seen in a while. Commented Dec 9, 2014 at 16:20

2 Answers 2

5
var blocks = document.getElementsByClassName('block');

That is not an array. It is array like. You need to make it into an array.

var elems = document.getElementsByClassName('block');
var blocks = Array.prototype.slice.call( elems, 0 );
Sign up to request clarification or add additional context in comments.

Comments

5

blocks is not an Array. It's a NodeList So you need to use [].slice.call which will take blocks, which is an array-like structure and return expected results.

var blocksArr = [].slice.call(blocks, 0); 
var blocksUSed = blocksArr.splice(0, 3);

6 Comments

Don't use splice! The nodelist will throw an error upon attempts to modify it!
@Bergi never heard of this. Any links? Any way I changed it
I just tried it out and got an Exception Failed to update length. Which makes only sense as length is specced to be readonly.
@Matthijs: Yes, now it does. This revision didn't.
@Matthijs I'm happy with +15 but perhaps it is epascarello who answered it correctly from the first and deserves it more. Bergi, thanks for that. Didn't knew it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.