Here's a silly one; Steve Harvey's suit combos

There’s a sound doing the rounds on TikTok of American comedian, Steve Harvey, laying out his formula for success in the realm of mens’ suits. He claims that from 5 colours of suits (matching jacket and trousers) and 3 colours of shirts, you could make 75 combinations because everything goes with everything else (subjective and outside the scope of this post).

Thought I’d see if he pulled this number out of thin air or not and test my JavaScript at the same time.

Here’s the base I made, using the web search function on attachments to pull in some pics and a scripting block to iterate through all the options and create the matching outfits.

Here’s my little script for those interested / want to grimace at my code;

let articlesTable = base.getTable('Articles')
let outfitsTable = base.getTable('Outfits')

let allArticles = await articlesTable.selectRecordsAsync()

let jackets = allArticles.records.filter((article) => article.getCellValueAsString('Item') === 'Jacket')
let trousers = allArticles.records.filter((article) => article.getCellValueAsString('Item') === 'Trousers')
let shirts = allArticles.records.filter((article) => article.getCellValueAsString('Item') === 'Shirt')

function createOutfits(jackets, trousers, shirts) {
    let outfits = []
    for (let jacket of jackets) {
        for (let trouser of trousers) {
            for (let shirt of shirts) {
                let outfit = {
                    jacket: jacket.id,
                    trouser: trouser.id,
                    shirt: shirt.id
                }
                outfits.push(outfit)
            }
        }
    }
    return outfits;
}

let outfits = createOutfits(jackets, trousers, shirts)

// output.inspect(outfits)

let outfitsToWrite = outfits.map(outfit => {
    return (
        {
            "Jacket": [{ id: outfit.jacket }],
            "Trousers": [{ id: outfit.trouser }],
            "Shirt": [{ id: outfit.shirt }]
        }
    )
})


for (let outfit of outfitsToWrite) {
    await outfitsTable.createRecordAsync(outfit)
}```

I really enjoyed this little challenge and thought, this might be the only place I can share it without getting laughed at or confused looks.
3 Likes

What a fun personal project!

I enjoyed looking at all the outfit combinations.

Are you interested in ways to speed up this little script? Or was it just fun and you are done with it?

1 Like

I definitely am interested in improvements, thank you!

I actually went looking for how to do permutations, first and found quite a complicated script on Stack Overflow that used recursion. When that came out with 75 I had a go at writing my own with the JavaScript that I know.

So I know it’s not the “best” method but I was pleased to have found my own.

That’s funny. When I first read your post, it reminded me of my daughter’s math homework where she had to calculate permutations and combinations.


Okay, here goes.


In this section you are creating records one at a time.

You can speed up your script by creating them in batches. This is probably the number one improvement that will be most useful to you when writing other scripts.

while (outfitsToWrite.length) {
    await outfitsTable.createRecordsAsync(outfitsToWrite.splice(0, 50)
}

You create the outfitsToWrite in multiple stages by identifying the permutations, and then mapping them to the write format. You could create them directly in the write format.

let outfit = {
            "Jacket": [{ id: jacket.id }],
            "Trousers": [{ id: trouserl.id }],
            "Shirt": [{ id: shirt.id }]
        }

You do not specify which fields you want in your query. It is good practice to specify the fields you need to reduce the amount of data loaded into memory. Instead of

try
let allArticles = await articlesTable.selectRecordsAsync({fields: ["Item"]})


When separating the articles into jackets, trousers, and shirts, you take three passes through the array.

You could do this in one pass through the array

const jackets = []
const trousers = []
const shirts = []

for (const article of allArticles.records) {
    switch (article.getCellValueAsString('Item')) {
        case "Jacket": jackets.push(article); break;
        case "Trousers": trousers.push(article); break;
        case "Shirt": shirts.push(article); break;
    }
}

These are all minor adjustments, and some of these suggestions are more a matter of style than anything else.

If you find yourself writing automation scripts, you may want to get in the habit of writing efficient scripts. Automation scripts have hard limits on how much time and memory a script can use.


Absolutely, give yourself a pat on the back. You code (1) works, and (2) was straightforward and easy to read. If I hadn’t seen potential in your script writing, I wouldn’t have bothered trying to help you improve.

There are multiple ways of doing things in code. There is no single “best” method. Write the best code that you can for who you are in the moment.

Plus, fun little side projects like this are a great way to work on building up coding skills.

1 Like

Thank you so much for such a kind and thoughtful response. I really appreciate the encouragement and the tips are all super useful and new to me (especially that filter in one pass one).

The only thing I already knew, but made a choice to do differently, was the batch create records; I purposefully went for one at a time so I could have the satisfaction of watching the gallery view fill up one-by-one.

Thanks again for your help, looking forward to putting it into practice on the next one.

2 Likes