Finding the first x words of a string

Apologies if this has been covered before, but I can’t find anything which I can understand enough to make work…

All I want to do is shorten titles to manageable sizes. I can do this easily enough if I don’t care about word boundaries.

$Name = $String.substr("0,49")

works well, but it’s ugly. I’d like to do the equivalent to pick up the first 10 words, like

$Name = $String.words("0,9")

to pick up the first 10 words. I can’t see anything like that.

Looking around I can see some possibilities, e.g.:

$MyList = $String.split("\W");
$ShortName = $MyList.at(0) + " " + $MyList.at (1) + ....

but that is going to get very tedious quickly.

I can’t see an operator / action to take the first x items of list, which means I need some sort of iteration.

I think I’m supposed to use $MyList.each(), but I can’t get it to work, and I’m not sure I’m understanding what’s going on. The atbref is helpful, of course, but I can’t get it work in these circumstances.

So, please:

a) is there an easier way which I’m just not seeing; or

b) is it possible to explain how to use .each() to do what I want?

Many thanks.

Have you tried

$MySring.words(10);

See this.

No, I hadn’t tried it – but it was exactly what I was looking for, of course!

I’d actually spent half an hour looking in atbref for something like it (then on list operators and all the other stuff, and had done a search for word on the sitemap page as well.
Goodness knows how I missed it…

Thanks very much!

Glad that works for you :slight_smile:

If you search the sitemap using ⌘F in Safari, and type “word” as the search string, Safari unhelpfully never shows you the result .word – you have to explicitly search for “.word”.

Yet another Safari bug.

1 Like

Ha – that will be it. Or it’s just creeping old age on my part… Either way, thanks!

Just to finish off the thread:

Using the first 15 words is OK until the first line of the text is so short that the 15 words includes line breaks. In case anyone else reads this and wonders about a workaround, here’s what I’ve found works:

$MyList=$Text.split("\n");
$ShortName=$MyList.at(0).words(15); 
$Name = $ShortName + " [...]"

This ensures that titles with less than 15 words are truncated properly and the continuation marker […] is added in the right spot. It works by splitting the entire text into a list, each item being a single paragraph (limited by \n), then creating a string with the first item of the list (at.(0)), restricted to fifteen words.

Or, simplified:

$Name=$Text.split("\n").at(0).words(15) + " [...]"

There may be a better way than this, but it seems to work.

1 Like

Nice. @brookter’s code is a very nice practical example of how to used chained ‘dot operators’.

$Name=$Text.split("\n").at(0).words(15) + " [...]"

To unpick the logic of this for later readers:

  • $Text.split("\n") splits the text at line breaks, returning a list of paragraphs.
  • Chaining the function .at(0) returns a string holding the contents of the first list item, i.e. the text of $Text’s first paragraph.
  • Chaining the function .words(15) returns a string holding only the first 15 words within that string.
  • That string is then concatenated with (i.e. joined) with the literal string " [...]".

Hopefully, that helps shows how the overall expression takes a string ($Text), chops it into a list before turning the output into a different string.

Cheers Mark!

At least I’ve recovered some face after missing the .words() operator in the original post…