4

Is it possible to exclude array indexes in a shuffle?

My insight in this question:

   Array[0,1,2,3,4,5,6,7,8]
   Exclude Array index 2 and 7 in shuffle.
   Shuffle Array.
   Array[3,5,2,1,6,8,0,7,4]

This is my what I used in my shuffle:

List<Pokemon>list = Arrays.asList(pkm);
Collections.shuffle(list);

EDIT:

Thanks, @Jhanvi! I studied your code and it gave me some ideas. I tried to play around with yours and @Rohit Jain's codes and created a sample:

import java.util.Arrays;

    import java.util.Collections;
    import java.util.List;
    import java.util.ArrayList;

public class Example {

 public static void main(String[]args){
    String[] x = {"a","b","c","d","e","f","g","h"};
    List<String> list = new ArrayList<String>(Arrays.asList(x));
    System.out.println("Before shuffling, ArrayList contains : " + list);
    Object obj = list.remove(7);
    Object obj1 = list.remove(2);
    Collections.shuffle(list);
    list.add(2, obj1);
    list.add(7, obj);
    System.out.println("After shuffling, ArrayList contains : " + list);        
 }     
}

Annoyingly it gives me an error: cannot find symbol method add(int,java.lang.Object) on both my list.add().

I checked that there exists a .add(int,Object) method for List, thinking that it will work. What part did I miss?

unknown
  • 4,859
  • 10
  • 44
  • 62
Rapharlo
  • 89
  • 6
  • Similar Question, for Python, but same problem: [Python: shuffling list, but keeping some elements frozen](http://stackoverflow.com/q/12238005/1639625) – tobias_k Oct 14 '13 at 11:46
  • You have taken your list in string format, and adding the elements in list which is supposed to be in int format, you need to typecast it and then add. list.add(2, (String) obj1) replace your add by this. – Jhanvi Oct 15 '13 at 07:56

2 Answers2

15

You can try something like this:

ArrayList arrayList = new ArrayList();
arrayList.add(0);
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
arrayList.add(4);
arrayList.add(5);
arrayList.add(6);
arrayList.add(7);
System.out.println("Before shuffling, ArrayList contains : " + arrayList);
Object obj = arrayList.remove(7); // remove by index!
Object obj1 = arrayList.remove(2);
Collections.shuffle(arrayList);
arrayList.add(2, obj1);
arrayList.add(7, obj);
System.out.println("After shuffling, ArrayList contains : " + arrayList);
sabadow
  • 5,095
  • 3
  • 34
  • 51
Jhanvi
  • 5,069
  • 8
  • 32
  • 41
  • +1 Clever way. Could be made better by using a `Map` with index as key, and value as value at the index. And also, use a parameterized `ArrayList`. – Rohit Jain Oct 14 '13 at 11:15
  • Sorry for my previous comment. `remove()` method doesn't return the element, but takes the element to remove. Got confused earlier, so deleted the comment. Your previous approach was fine. Sorry again for that misleading comment. – Rohit Jain Oct 14 '13 at 11:35
  • @RohitJain: `remove()` returns the element if you remove by index. It's a bit confusing in this case since the values look like indexes but `int` should bind over `Integer`. – Aaron Digulla Oct 14 '13 at 11:41
  • @AaronDigulla , while removing we have to decrease the index, because already 1 elemnt in removed from the array, hence the edit. – Jhanvi Oct 14 '13 at 11:45
  • @Jhanvi: You're right. In this case, you can remove from the end (i.e. first 7, then 2). – Aaron Digulla Oct 14 '13 at 11:47
  • @RohitJain you were not wrong. `ArrayList` has two `remove()` methods, one taking an `int` as argument and returning the removed object and a second one which takes the object to be removed as argument and returns `true` or `false`, depending on the success of operation. See [remove(Object)](http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#remove%28java.lang.Object%29) and [remove(int)](http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#remove%28int%29). – Mauren Oct 14 '13 at 11:49
  • @Jhanvi Why did you rollback? My change was much more readable – Shervin Asgari Oct 14 '13 at 11:50
  • @Shervin , in your edit, the remove() was used differently. I had edited the remove() method, use the same in yours, and edit. – Jhanvi Oct 14 '13 at 11:51
  • @AaronDigulla Ah! When the value in list are of type `Integer`, then the method `remove(index)` start behaving awkward. – Rohit Jain Oct 14 '13 at 11:52
  • @RohitJain: It really shouldn't (perfectly matching types beat autoboxing) but readers of the code will be confused why the "2" in `remove()` is not the same as the one in the `add()`. – Aaron Digulla Oct 14 '13 at 11:54
  • @Shervin Please check whether your edits work or not before editing. Your current edit won't even compile. – Rohit Jain Oct 14 '13 at 11:55
  • @Shervin , your code is giving error, hence the rollback again. – Jhanvi Oct 14 '13 at 11:55
  • @AaronDigulla Yeah but return type would always be taken as `boolean` with element type as `Integer`. – Rohit Jain Oct 14 '13 at 11:56
  • @Jhanvi instead of rollback, you can just fix the typo :) – Shervin Asgari Oct 14 '13 at 11:58
  • @RohitJain: `remove(2)` means `Integer remove(int)` will be selected. – Aaron Digulla Oct 14 '13 at 11:59
  • You cant print out the content of a arraylist like that. – Shervin Asgari Oct 14 '13 at 11:59
  • @AaronDigulla Yeah, that is what I was pointing to. So, just a `remove()` won't work here. – Rohit Jain Oct 14 '13 at 12:00
  • @RohitJain , have tried it with different elements in array, its working – Jhanvi Oct 14 '13 at 12:03
  • Ah you're right. I didn't know AbstractCollection has overriden the toString. – Shervin Asgari Oct 14 '13 at 12:04
  • @RohitJain array contains 0,1,2, .. etc , hence the confusion, if you try using different integers , it works – Jhanvi Oct 14 '13 at 12:04
  • @RohitJain , yeh that's y i didnt take List , as OP has not mentioned integer in list – Jhanvi Oct 14 '13 at 12:05
2

You could create a shuffle yourself: just pick two indexes at random, making sure you exclude the ones you want to exclude, and swap the array elements in those positions. Repeat enough times.

Eduardo
  • 8,362
  • 6
  • 38
  • 72