Search code examples
javascriptarraysscopeselectionrecycle

Function param array, how to affect reference = [] or reference.concat(array2)?


So it could just be I'm crazy tired but I can't seem to figure this out.

I've been picking up javascript which I'm finding horrible coming from actionscript 3 where everything was typed. I had a function that referenced two array variables directly, I later needed to use it again for a different data set so I've altered it to take parameters and now it's breaking.

I have one array full of elements, the 2nd is empty. When I call the function, a random element is removed from the first array and pushed into the 2nd array, that element is also returned by the function. If the 1st array is empty I have concat the 2nd array to fill it back up. The goal was to randomly iterate through the elements and not have the selected elements show up again until I had finished a full cycle.

Prior to concat I was using slice(which should work just as well?), the problem I believe is that I know have a parameter that is redefined when I do 'array = array2.slice()', concat doesn't seem to work around that. I don't know if returning the single sliced element from the first array is bad if I'm expecting a string, I think slice is returning an array with the single element, easy fix there though by adding [0] to the return statement.

Heres the code:

//Gets a random element from array, that element is moved from the 'src' array to the 'bin' array,
//this allows random selection without choosing the same element until all of 'src' array elements have been picked
function getRandomElement(array_src,array_bin){
    //Randomly selects a tweet from the que, then stores it in another array so each tweet shows once before recycling
    if(array_src.length==0 && array_bin.length>0) {array_src.concat(array_bin);} //Recycles array elements when the src array is empty
    var randomElement = array_src.splice(Math.floor(Math.random()*array_src.length),1); //Grab a random array element
    array_bin.push(randomElement);//array elements stored here to be recycled

    return randomElement;
}

I think I could maybe use an object with two properties pointing to the arrays and pass those in, though it'd be nicer if there is a better way. I could also use push on array_src looping through the array_bin to work around that issue if there isn't any other way.

I wouldn't say this is a duplicate Felix. The answer you provided is pretty much the same, but the question itself is phrased differently, I wasn't aware of the term mutate, finding the question/answer wouldn't be easy, none of the suggested links SO provided were relevant. Worth keeping up for making the answer more discoverable to those unaware of the mutate term.


Solution

  • I have a hard time understanding the problem, but I think you are wondering why array_src.concat(array_bin) doesn't seem to do anything?

    That's because .concat returns a new array. If you want to mutate the existing array_src array, you can use .push:

    array_src.push.apply(array_src, array_bin);
    

    FWIW, this has nothing to do with strong typing. JavaScript (and I guess ActionScript as well), is pass-by-value. That implies that assigning a new value to array_src doesn't change the value of the variable that was passed to getRandomElement.

    But since arrays are mutable in JavaScript (and ActionScript I assume), you can mutate the array itself.