AllWordCombinations ( theWords )
List all possible subsets from a string of words
Average rating: 4.2 (33 votes) Log in to vote
Michael Kupietz - Show more from this author
Michael Kupietz FileMaker Consulting https://michaelkupietz.com |
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, 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, Germany 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 |
||
Michael Kupietz, Michael Kupietz FileMaker Consulting 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, Germany 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, 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, Monk Media 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, 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, San Francisco, CA Apr 9, 2017 |
||
Oops, there shouldn't have been a space in "XYZABCSLASHXYZABC", above. | ||
Ronnie Higgins, Anaheim Mar 7, 2018 |
||
Is there a way to exclude specific words (ie: "and", "the" ) ? | ||
Ronnie Higgins, Anaheim Mar 7, 2018 |
||
Can it be made to restrict the outcome to only consecutive word combinations? | ||
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, 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. |
||
Note: these functions are not guaranteed or supported by BrianDunning.com. Please contact the individual developer with any questions or problems.