0

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.

3
  • Your update explains exactly why this question SHOULD be marked as a duplicate. For people that aren't aware of the terminology. This is a book keeping measure and not meant as a slight against you. Commented Aug 21, 2014 at 17:18
  • That's ok, I'm not very familiar with what the marked as duplicate meant, was thinking at the time I was asked to justify keeping the duplicate up otherwise it'd be deleted. I think I misunderstood that :) My point was to keep the question available so those who don't know the term mutate would come across this and learn. Commented Aug 22, 2014 at 12:33
  • No problem. Questions only get deleted if there are very poor quality (this isn't). Commented Aug 22, 2014 at 16:49

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

8 Comments

so concat would be similar to how I was handling it with slice? Since I'm not using the actual variable for the array but a paramter referencing it, array=array.concat(array2) would not update my actual array outside of the function. That's my problem.
a.concat(b) simply creates a new array containing all elements of a and b. It doesn't change a or b in any way. a.slice(i) also doesn't change a, it just returns a new array containing all elements of a starting at index i. I tried to explain why assigning a new value to array_src doesn't work (JavaScript is pass-by-value).
Apologies about the comment on strong typing, it's not relevant to the issue, but I do miss the benefits I had from having such. I tried your push.apply, it doesn't appear to be working. I'm seeing a single value within an array be stored. So [[value]] instead of [value, value, value, etc]
Oh, you also have to do array_bin.push(randomElement[0]); since .splice always returns an array.
I get why it doesn't work when I previously assigned it to array_src with the returned sliced array(I wasn't familiar with concat). Is there a proper way around this or do I need to store my arrays in an obj?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.