Brian Dunning's FileMaker Custom Functions

AllWordCombinations ( theWords )

List all possible subsets from a string of words

  Average rating: 4.2 (33 votes) Log in to vote

Mike Kupietz   Mike Kupietz
http://www.kupietz.com

Share on Facebook Share on Twitter

  Sample input:
AllWordCombinations("boy girl cat dog")
  Sample output:
boy
boy girl
boy girl cat
boy girl dog
boy girl cat dog
boy cat
boy dog
boy cat dog
girl
girl cat
girl dog
girl cat dog
cat
dog
cat dog

  Function definition: (Copy & paste into FileMaker's Edit Custom Function window)

Given a string of words separated by spaces, this function returns a list of every unique combination of one or more of those words. For instance, AllWordCombinations("boy girl cat dog") will return:

"boy
boy girl
boy girl cat
boy girl dog
boy girl cat dog
boy cat
boy dog
boy cat dog
girl
girl cat
girl dog
girl cat dog
cat
dog
cat dog"

Please note: this returns all combination, not all permutations. "Boy cat" and "Cat boy" are two different permutations, but the same combination. A fruit salad made of apples and grapes is the same as a fruit salad made of grapes and apples.

 

Comments

Charlie   Charlie, Cincinnati
Nov 12, 2015
Wouldn't a missing combination be:

girl boy cat
girl boy cat dog
cat boy
cat boy girl
cat boy girl dog

etc.
 
Thomas   Thomas, Paris
Dec 6, 2015
Is there a way to handle duplicates ?
For example with entry : (boy boy girl girl dog) ?

boy
boy boy
boy boy girl
boy boy girl dog
boy boy dog
boy girl
boy girl girl
boy girl dog

etc..

girl
girl girl
girl girl dog
girl dog


Thanks
 
Mike Kupietz   Mike Kupietz, CA
Dec 7, 2015
Charlie, this function returns all combinations. Technically you're talking about permutations not combination. "Boy cat" and "cat boy" are different permutations, but the same combination of words. A "combination lock" is misnamed, because it requires the correct permutation of numbers, not just the correct combination of numbers. But a fruit salad is a combination of fruit – one made of apples and grapes is the same as one made of grapes and apples.

Thomas, because this function use as a substitute, I believe, looking at it, that it will simply ignore duplicates. (It's been along time since I posted it, I don't remember specifically how it works.) So it would probably need to be rewritten to preserve duplicates. If you absolutely didn't know how to do that, I would kludge it by making the input list contain "boy1" and "boy2" instead of just the word "boy" twice.
 
Thomas   Thomas, Paris
Dec 11, 2015
Thanks. That's what i did. (boy1, boy2) I asked in the way to understand the programmation.

In the same way, is there a way to limit the number of combinations ?
For example : For 10 elements only the combinations of 5 or less.
 
Michael E. Kupietz, FileMaker Consultant   Michael E. Kupietz, FileMaker Consultant, San Francisco, CA
Sep 29, 2016
Thomas, off the top of my head, I'm sure there is. Off the top of my head, before you call the function recursively from within itself, you could just do a wordcount() on the value you're about to call it on, and if it's reached maximum length, don't make the recursive call.
 
Rob   Rob, Nevada
Apr 9, 2017
Great function, has really come in handy for me. Thanks! I'm wondering if there's any way to support characters like dashes and slashes and underscores in the words. I tried changing the functions from WordCount, LeftWords, RightWords to ValueCount, LeftValues, and RightValues, but all I get is a single line of text with each of the words. I'm using this to build a record tagging feature and would like to be able to support characters like - / and $ in my tags. Thanks!
 
Michael E. Kupietz, FileMaker Consultant   Michael E. Kupietz, FileMaker Consultant, San Francisco, CA
Apr 9, 2017
Well, this is a kludge, but off the top of my head the very easiest thing to do would be to run the input string through a substitute function before passing it to the custom function, and change those characters to letter strings unlikely to be used elsewhere. For instance:

substitute(string, ["-","XYZABCDASHXYZABC"],["/","XYZABCSLASHXYZABC"],["$","XYZABCDOLLARXYZABC"])

so they become embedded as text into the surrounding words ("tag1-subtag1" becomes "tag1XYZABCDASHXYZABCsubtag1") and treated as single words by the function. Then just do the reverse substitution on the output of the function to replace those strings with the original punctuation.

Glad you're finding it useful, thanks!
 
Michael E. Kupietz, FileMaker Consultant   Michael E. Kupietz, FileMaker Consultant, San Francisco, CA
Apr 9, 2017
Oops, there shouldn't have been a space in "XYZABCSLASHXYZABC", above.
 
Ronnie Higgins   Ronnie Higgins, Anaheim
Mar 7, 2018
Is there a way to exclude specific words (ie: "and", "the" ) ?
 
Ronnie Higgins   Ronnie Higgins, Anaheim
Mar 7, 2018
Can it be made to restrict the outcome to only consecutive word combinations?
 
Michael E. Kupietz, FileMaker Consultant   Michael E. Kupietz, FileMaker Consultant, San Francisco, CA
Mar 7, 2018
You can easily exclude specific words by putting a substitute() in the beginning of the function to replace theWords with substitute(theWords,["the",""],["and",""],...).

To make this simpler, I'd probably run the whole thing through lower() too... substitute(lower(theWords),["the",""],["and",""],...) since "the" will not match "The" in a substitute function().
 
Michael E. Kupietz, FileMaker Consultant   Michael E. Kupietz, FileMaker Consultant, San Francisco, CA
Mar 7, 2018
As for your second question, if I'm understanding you correctly, you only want it to return combinations that appear in order... so AllConsecutiveWordCombinations("boy girl cat dog") would return:

"boy
boy girl
boy girl cat
boy girl cat dog
girl
girl cat
girl cat dog
cat
dog
cat dog"

This is possible in the abstract, but complicated because of the way the function works. If I wanted to do this in a real-life situation, where I wanted to get it done quickly rather than having fun with the challenge, I might just write a second recursive function that compares every value in a list to a given string, then omits values that don't appear in that string (using, say PatternCount to determine this.)

Something like:

omitNonconsecutive(firstCFresults,compareString) =

if (
patterncount ( compareString ; getvalue ( firstCFresults ; 1 ) ) > 0 ;
getvalue ( firstCFresults ; 1 ) & "¶" ;
""
) &
if (
valuecount ( valueList ) > 0 ;
omitNonconsecutive (
rightvalues ( firstCFresults ; valuecount ( firstCFresults ) - 1 ) ;
compareString
) ;
""
)

Then you could just do omitNonconsecutive(AllWordCombinations("boy girl cat dog"),"boy girl cat dog") to get only the consecutive combinations.

I haven't tested the above, though. It's just the general idea.

Alternatively you could also adapt an "explode text" function (found elsewhere on this site) to do it with one function.
 

Log in to post comments.

 

Note: these functions are not guaranteed or supported by BrianDunning.com. Please contact the individual developer with any questions or problems.

Under construction. Email me your wish list for improvements.