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.

Brennan
  • 305
  • 4
  • 19
  • 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. – JasonMArcher Aug 21 '14 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. – Brennan Aug 22 '14 at 12:33
  • No problem. Questions only get deleted if there are very poor quality (this isn't). – JasonMArcher Aug 22 '14 at 16:49

1 Answers1

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.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 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. – Brennan Aug 21 '14 at 16:04
  • `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). – Felix Kling Aug 21 '14 at 16:06
  • 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] – Brennan Aug 21 '14 at 16:11
  • Oh, you also have to do `array_bin.push(randomElement[0]);` since `.splice` *always* returns an array. – Felix Kling Aug 21 '14 at 16:12
  • 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? – Brennan Aug 21 '14 at 16:12
  • You can use what I suggested in my answer. – Felix Kling Aug 21 '14 at 16:14
  • I've done the push.apply along with randomElement[0]. It is pushing the array_bin contents into array_src, but array_bin isn't losing it's contents after. Any ideas? – Brennan Aug 21 '14 at 16:43
  • You can empty the array using `array_bin.length = 0;`. This is btw also explained in the duplicate question. – Felix Kling Aug 21 '14 at 16:43