Finding all combination of items in a string to then present to participant

I am trying to find all combinations of each two items in a list, such that:

items = ['A', 'B', 'C'] 

Would become:

combinations = ['A B', 'B C', 'A C']

In python this works very easily with:

itertools.combinations(items, 2))

This is what I have so far, for a 20 item long list, the output technically should be of 380 combinations. I am getting two error, the first being that the same item gets paired with itself (e.g., ‘A’ with ‘A’), the second being an actual code error when I later display the output as text:

TypeError: new_array2[combo_num] is undefined

Here is what I got, where combo_num holds twenty string items:

chose = 0
tmp = []
combo_num = 0
m2=[]
for i in range(400):
    m2.append(i)
for i in range(len(m2)):
    chose = randint(0,len(m2)-1)
    tmp.append(m2[chose])
    m2 = m2[:chose] + m2[chose + 1:]


def n_length_combo(lst, n):
    if n == 0:
        return [[]]
    l =[]
    for i in range(0, len(lst)):
        m = lst[i]
        remLst = lst[i+1:]
        remainlst_combo = n_length_combo(remLst, n-1)
        for p in remainlst_combo:
             l.append([m, *p])
    return l
   

new_array = n_length_combo(combo_list, 2)
new_array2 = util.shuffle(new_array)

Text is later displayed with:

combo_1.text = new_array2[combo_num][0]
combo_2.text = new_array2[combo_num][1]

I’d be happy with any solution, even one that doesn’t use the above code. Thanks!

Hi @Si_qwerty,

why don’t you just use itertools? It should work in PsychoPy as well.

I believe it breaks when I try and push it to Pavlovia (JS doesn’t properly read the script).

When I insert:

‘’’
import itertools
‘’’

The experiment gets stuck on the initializing experiment screen. I believe JS can’t read the code within itertools.

Ah, ok. You did not say that you want to use this online. This is a JS alternative:

var items = ["A", "B", "C"];

var combinations = items.flatMap(
    (v, i) => items.slice(i+1).map( w => v + ' ' + w )
);

taken from here.

Instead of using auto-translate, set the code component to “Both” and insert this code on the righthand side.

Thank you for the help ajus. I tried using this code but unfortunately I am receiving an error message:

ReferenceError: combinations is not defined

Seeing as the text I am trying to find the combinations for is defined during the experiment, and saved in its own variable called combo_list, this is what I changed the code to:

var items = combo_list;

var combinations = items.flatMap(
    (v, i) => items.slice(i+1).map( w => v + ' ' + w )
);

And I also tried this to no avail:

var combinations = combo_list.flatMap(
    (v, i) => combo_list.slice(i+1).map( w => v + ' ' + w )
);

I am later trying to visualize the combinations list with:

text1.text = combinations[trialnumber]

which is throwing the error. trialnumber is simply a number from 1 to the length of combinations.

For more reference, when I print combo_list I get the following list in the developer console:

Array(20) [ "q\n", "w\n", "e\n", "r\n", "t\n", "y\n", "aos\n", "wer\n", "trt\n", "f\n", … ]

Hi! I just tried this, and it works fine:

combinations = combo_list.flatMap(
    (v, i) => combo_list.slice(i+1).map( w => (v + ' ' + w).split(" ") )
);

Note: the var is gone and the string is split into two elements. So you can use the two elements of each combination by combinations[trialnumber][0] and combinations[trialnumber][1]

How about the following?

combinations = []
for Idx in range(len(items)):
     for Jdx in range(Idx+1,len(items)):
          combinations.append(items[Idx] + ‘ ‘ + items[Jdx])

I tried this:

var items = combo_list;

combinations = []
for (Idx in range(len(items)):
     for (Jdx in range(Idx+1,len(items)):
          combinations.append(items[Idx] + ‘ ‘ + items[Jdx])


but the experiment gets stuck on initializing the experiment. With the following error in the debugger:

Uncaught SyntaxError: missing ) after for-loop control

I added a ( bracket after the ‘for’ statements because I was getting this error:

Uncaught SyntaxError: missing ( after for

Please try using an auto translate code component

I tried the code you provided in AutoJS but the box to the right prompt a syntax error (fix Python code).

On a separate attempt, I tried the following code:

var array = combo_list;
resultrjt = []
var resultrjt = array.reduce( (acc, v, i) =>
    acc.concat(array.slice(i+1).map( w => v + ' ' + w )),
[]);

console.log(resultrjt);

It seems that the code is actually working within the routine where I input this code, in the sense that when I print it with console.log I indeed get the 190 combinations that I am looking for. When printing it again in the next routine though, with the same code

console.log(resultrjt);

That’s when the resultrjt variable returns as undefined. Do you know of any reason why a variable generated this way with JS code shouldn’t carry over from one routine to the next?

@Si_qwerty, just in case you missed it: This works: Finding all combination of items in a string to then present to participant - #6 by ajus

See here:
combinations.psyexp (10.9 KB)

The problem with this Python code was the apostrophes, which came out as smart on my phone, even though I was using preformatted text

I ended up using ajus’s code and it actually works perfectly!

Can’t thank you both enough!!