mardi 2 mai 2017

How to randomize multiple array elements between indexes?

I have an array of objects that looks like this: http://ift.tt/2pSXqkR

Each entry is an object within that array. What I need to do is randomize the order of each element that is NOT a headline. Each headline must remain at the initial index, but the elements between two headlines must be randomized. In the attached picture is a depiction of how it should look like.

The only difference between a headline and a regular element is that its value is a regex that looks like this #H#[0-9]+

So, what I did was: I iterate through the array, noting the indexes of each headline.

Then, iterate through the indexes array and split the array into multiple, smaller arrays (one group for every headline).

Then, iterate yet AGAIN through the array that contains the split arrays, splice each array starting at index 0 (remove the headline element), shuffle these values, unshift the array and add the headline element at the beginning.

Finally, concatenate all the arrays in splittedArrayOfArrays into the array that I need, which is current.choices.

Performing three iterations doesn't seem very wise in performance, is there any other possible way of randomizing only groups of elements from an array?

Here's the code I hacked together to make it work:

                    var headlineIndexes = [];
                    var splittedArrayOfArrays = [];
                    for (var ii = 0; ii < current.choices.length; ii++) {
                        if (regex.test(current.choices[ii].value)) {
                            headlineIndexes.push(ii);
                        }
                    }
                    for (var ii = 0; ii < headlineIndexes.length; ii++) {
                        //if there is another headlineIndex, split Array until that index
                        if (headlineIndexes[ii + 1]) {
                            splittedArrayOfArrays[ii] = current.choices.slice(headlineIndexes[ii], headlineIndexes[ii + 1])
                        }
                        //if not, split until end of array
                        else {
                            splittedArrayOfArrays[ii] = current.choices.slice(headlineIndexes[ii]);
                        }
                    }
                    current.choices = [];
                    for (var ii = 0; ii < splittedArrayOfArrays.length; ii++) {
                        //remove first element and store in firstElem
                        var firstElem = splittedArrayOfArrays[ii].splice(0, 1);
                        //call shuffle with remaining elements, which shuffles the elements WITHOUT the headline
                        shuffle(splittedArrayOfArrays[ii]);
                        // re-add the headline as first elem of splittedArray
                        splittedArrayOfArrays[ii].unshift(firstElem[0]);
                    }
                    current.choices = splittedArrayOfArrays.reduce( function(prev, next) {
                        return prev.concat(next) ;
                    });




Aucun commentaire:

Enregistrer un commentaire