.split() and .substring() difficulty

When parsing player/user input .replace() simply ignores if it can't find any examples and then continues the script. No problem.

However, .split() stops the script (and any script after it) if it can't find any examples. Very annoying. The script below works correctly a maximum of three times, but you can easily see how hairbrained the work-around is.

@set meal = I had a Taiwanese crêpe omelette with shiitake mushrooms, Thai basil, and cheddar, and a glass of boba milk tea.

    //add 1 to the count of a noun following "s of", so that future parsing will treat it as plural.
    var food = squiffy.get("meal") + " plates of bowls of cups of "; //appending this at the end of a player input keeps it from quitting a maximum of three times.
    var unit = food.replace(/[.,]/g, "");
    var unit1 = unit.split(/[es|ls|ps|gs|ns] of/)[1].split(' ')[1];
    squiffy.set(unit1, squiffy.get(unit1) + 1);
    var unit2 = unit.split(/[es|ls|ps|gs|ns] of/)[2].split(' ')[1];
    squiffy.set(unit2, squiffy.get(unit2) + 1);
    var unit3 = unit.split(/[es|ls|ps|gs|ns] of/)[3].split(' ')[1];
    squiffy.set(unit3, squiffy.get(unit3) + 1);
    //end of "s of"

However, .split() stops the script (and any script after it) if it can't find any examples.

I don't think that's what's happening.

You start out with a string, unit.

You use the expression unit.split(/[es|ls|ps|gs|ns] of/) to split this string up into an array, split up where the ".s of" is. Then you take the 2nd, 3rd, and 4th elements of this array and use .split(' ') on them.

Using .split(' ') on a string that doesn't have a space in would just not split it.
Using .split(' ') on the 4th element of a list that only has 3 elements causes an error; because split only works on a string.

You should check how many elements are in the list, and only do things to the ones that actually exist.
I'm not sure I really understand what you're trying to do here; but I think you could do something like:

    var units = unit.split(/[es|ls|ps|gs|ns] of/);
    for (i=1 ; i < units.length ; i++) {
        var currentunit = units[i];
        squiffy.set(currentunit, squiffy.get(currentunit) + 1);
    }

Yeah, I gave a really bad example that (1) doesn't even show what I want to do and (2) has regex mistakes. Yikes. You're always so kind that it's hard to figure out how dense I'm being. 😊 Here's another, hopefully better.

@set meal = I had a glass of milk, two bowls of oatmeal, and several strips of bacon with eggs on two pieces of toast. But my whole cups of butter won't get counted. Yay!
var food = squiffy.get("meal") + " plates of bowls of cups of "; //appending this at the end of a player input keeps it from quitting a maximum of three times.
    var unit = food.replace(/[.,]/g, "");
    var unit1 = unit.split(/[elpgn]s of/)[1].split(' ')[1];
    squiffy.set(unit1, squiffy.get(unit1) + 1);
    var unit2 = unit.split(/[elpgn]s of/)[2].split(' ')[1];
    squiffy.set(unit2, squiffy.get(unit2) + 1);
    var unit3 = unit.split(/[elpgn]s of/)[3].split(' ')[1];
    squiffy.set(unit3, squiffy.get(unit3) + 1);

The result is

meal = I had a glass of milk, two bowls of oatmeal, and several strips of bacon with eggs on two pieces of toast. But my whole cups of butter won't get counted. Yay!
oatmeal = 1
bacon = 1
toast = 1

The script I already have working already counted each food as one, making the result

milk = 1
oatmeal = 2
bacon = 2
egg = 2
toast = 2
butter = 1

I don't think any player is likely to use more than three collective nouns in one prompt, but it would be nice to have it work if they do.


I don't think any player is likely to use more than three collective nouns in one prompt, but it would be nice to have it work if they do.

That's another reason to use for (or forEach) rather than manually doing the same thing for elements 1, 2, and 3 from the list.

Actually… looking at your expressions, it seems that you're just taking the first word after each instance of /[elpgn]s of/ … in which case, using split seems to be a pretty unusual way of doing it. I'd probably suggest simplifying to something like:

    unit.matchAll(/[elpgn]s of *(\w+)/g).forEach(match => {
        squiffy.set(match[1], squiffy.get(match[1]) + 1);
    });

matchAll finds every place a regex matches in a string; and forEach goes over the array doing the same thing for each item.

Within the foreach loop, match[0] will be something like "ps of butter" and match[1] will be "butter" (the first set of parentheses in the regex).


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums