-2

First of all sorry for the long title, I really didn't know how to word it better.

In the middle of solving _.shuffle in underscore, I encountered the use of splice. Here is my original code :

shuffle = function(array) {
  var shuffledArray = [];
  var total = array.length;
  var copiedArray = array.slice();
  while (total){
    var randomNum = Math.floor(Math.random() * total);
    shuffledArray.push(copiedArray.splice(randomNum,1));
    total--;
  }
  return shuffledArray;
};
var originArray = [1, 2, 3, 4];
console.log(shuffle(originArray));

However after testing just I realized it will return each value inside a [ ], instead of just the value.

i.e.

[ [ 4 ], [ 3 ], [ 1 ], [ 2 ] ]
//instead of [ 4, 3, 1, 2]

When I changed this line (added '[0]' after the deleteCount in splice)

shuffledArray.push(copiedArray.splice(randomNum,1));

into this

//edited
shuffledArray.push(copiedArray.splice(randomNum,1)[0]);

the return array that I get is what I wanted, which is

[ 3, 1, 2, 4 ] //values are not in [ ]

Can someone explain how adding [0] after splice() makes the value not return in [ ] or why not having [0] does?

Tinah
  • 7
  • 2
  • 1
    `1[0]` return _undefined_ so you call same as `copiedArray.splice(randomNum)` – Grundy Sep 23 '15 at 08:18
  • 1
    i not quite understand what you try to do? – Grundy Sep 23 '15 at 08:20
  • 1
    @Grundy: `1[0]` is indeed `undefined`, but `copiedArray.splice(randomNum)` and `copiedArray.splice(randomNum, undefined)` are **not** the same thing. – T.J. Crowder Sep 23 '15 at 08:21
  • I'm just trying to understand why writing 1[0] will return the value as is and not inside [ ] – Tinah Sep 23 '15 at 08:21
  • Are you sure you're not using `copiedArray.splice(randomNum,1)[0]`? – ralh Sep 23 '15 at 08:22
  • 1
    @Tinah: As far as I can tell, `copiedArray.splice(randomNum, undefined)` returns a blank array. Your question is unclear about what you're trying to do, why you would ever think of doing `1[0]`, your ultimate goal... – T.J. Crowder Sep 23 '15 at 08:22
  • @T.J.Crowder, yep, you right :-) with _undefined_ returned empty array – Grundy Sep 23 '15 at 08:22
  • @Luaan: You mean, like, [the specification](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-array.prototype.splice)? Note the opening words relate to the number of arguments, not what their values are. Or you can open a console in a browser and try it. – T.J. Crowder Sep 23 '15 at 08:24
  • @Tinah, i think you want `[0]` after `splice` like `array.splice(0, 1)[0]` – Grundy Sep 23 '15 at 08:24
  • @T.J.Crowder Browser are known to differ in details like this, but yeah, the spec link is exactly what I wanted :) And just to note, when I try Tinah's code in Chrome, it works *exactly* as with `undefined` (because, well, `1[0]` *is* `undefined`). – Luaan Sep 23 '15 at 08:25
  • @T.J.Crowder @ralh yes you're right, I was using `copiedArray.splice(randomNum,1)[0]` not, `copiedArray.splice(randomNum,1[0])` smh – Tinah Sep 23 '15 at 08:25
  • so does adding [0] just mean the element I removed is now being added to the zero index of the new array? – Tinah Sep 23 '15 at 08:26
  • @Tinah, are you sure that you need `splice`? do you see [doc](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)? – Grundy Sep 23 '15 at 08:27
  • No :) You're simply taking the first element of the (single element) array returned by `splice`, and pushing that. – Luaan Sep 23 '15 at 08:29
  • @Luaan yea, now I see it. I am just pushing the zero index of the array that splice() extracted. Thank you. – Tinah Sep 23 '15 at 08:42

4 Answers4

1

splice returns an array. When you push an array into an array, you get an array of arrays. By adding the [0], you push the first element of the array instead. This is no Javascript weirdness - it's perfectly reasonable.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • @Tinah It's a very weird misunderstanding, I must say. Frighteningly, I can imagine this working the way you (wrongly) expect in some unsafe language like C under some specific conditions - and failing miserably in real world use once in a while. – Luaan Sep 23 '15 at 08:31
  • I think I was more confused when I thought my code was `copiedArray.splice(randomNum,1[0]` now that I realized that mistake. It makes sense. – Tinah Sep 23 '15 at 08:35
0

As I suspected and was confirmed in the comments, you were using copiedArray.splice(randomNum,1)[0], not copiedArray.splice(randomNum,1[0]).

EDIT: That was the original question, and it was since edited.

And since splice returns an array (in your case, an array with one number), taking the first element of the array achieves exactly what you wanted.

ralh
  • 2,514
  • 1
  • 13
  • 19
0

Splice returns an array of the deleted elements. By adding [0] you are effectively selecting the first item in the returned array.

Armando Canals
  • 290
  • 1
  • 7
-2

Try not to reinvent the wheel ! http://php.net/manual/fr/function.shuffle.php

If you really want to, try this in your while:

  while (total){
    var randomNum = Math.floor(Math.random() * total);
    ShuffledArray[] = array[randomNum]; //add an item to next pos
    unset(array[randomNum]); //remove the item added
    array = array_values(array); //reindex array
    total--;
  }

Best of luck !

Axel Lavielle
  • 252
  • 1
  • 12