Message Boards Message Boards

1
|
2729 Views
|
4 Replies
|
3 Total Likes
View groups...
Share
Share this post:

Looking for a similar function to Fold[ ]?

Posted 3 years ago

My current project has me creating yet another data mart using Microsoft Dynamics (a CRM solution) as the source. I have nearly 200 tables each having up to several hundred columns.

Unfortunately, the table and column names are a concatenation of words with no capitalization.

So, in order to help me build some documentation, and eventually the SQL for the data mart, I need to turn the gibberish into something the team (and our users) can easily read.

For example, I want to have a function to work like this:

strSeparateWords["fourscoreandsevenyearsago", {"four", "score", 
  "seven", "and", "seven", "years", "ago"}, "Capitalize" -> True]

to return:

"Four Score And Seven Years Ago"

While I was able to write such a function, I cannot help but think that there is a better (more Wolfram-like) solution.

Here is my solution:

Options[strSeparateWords] = {
   "Capitalize" -> False
   };

strSeparateWords[string_String, word_String, opt : OptionsPattern[]] := 
  Module[
   {
    replacement = If[OptionValue["Capitalize"], Capitalize[word], word]
   },
   StringTrim@StringReplace[string, word -> " " <> replacement]
   ];

strSeparateWords[string_String, words_?matchListOfStringsQ, 
   opt : OptionsPattern[]] := Module[
   {
    retVal = string
    },
   Do[
    retVal = strSeparateWords[retVal, word, opt]
    ,
    {word, words}
    ];
   retVal
   ];

I was hoping to find a function similar to Fold[] that works with single argument functions. In other words, I want a function that worked like this:

anotherFold[
 f[initialValue, #] &,
 { a, b, c}
 ]

would return:

f[f[f[initialValue, a], b], c]

As you can see, I cannot even figure out a good name for such a function. But I think it would be useful to have a generic function like this.

I've searched the documentation and web for over an hour now. But, before giving up, I wanted to ask the Community.

Thanks, and have a great weekend.

POSTED BY: Mike Besso
4 Replies
Posted 3 years ago

Rohit:

Thank you for the clarification.

POSTED BY: Mike Besso
Posted 3 years ago

Rohit:

Thank you. I missed how flexible Fold[] can be.

In this use case, order definitely matters. I am have to turn several thousand table/column names that look like "accountcategory" and "maximiumprobableloss" to "Account Category" and "Maximum Probable Loss".

Again, thank you for your insight.

Have a great weekend.

POSTED BY: Mike Besso
Posted 3 years ago

Hi Mike

In this use case, order definitely matters

What I meant is that the order of words in the list does not have to match the order in the candidate, the candidate will be split correctly. Using your last example

words = {"account", "category", "maximum", "probable", "loss"};

Randomizing words does not change the result

StringCases["accountcategory", Alternatives @@ RandomSample@words]
(* {"account", "category"} *)

StringCases["maximumprobableloss", Alternatives @@ RandomSample@words]
(* {"maximum", "probable", "loss"} *)
POSTED BY: Rohit Namjoshi
Posted 3 years ago

Hi Mike,

What is the difference between this and what is shown above for the desired output?

ClearAll[a, b, c, f, initialValue]
Fold[f, initialValue, {a, b, c}]
(* f[f[f[initialValue, a], b], c] *)

In the example for strSeparateWords it seems the list of words that define the splits is known. If that is the case then maybe something like this?

words = {"four", "score", "seven", "and", "seven", "years", "ago"};
StringCases["fourscoreandsevenyearsago", Alternatives @@ words] // Map[Capitalize] 
(* {"Four", "Score", "And", "Seven", "Years", "Ago"} *)

The order does not matter and the list can contain other words to split on that are not in the candidate.

words = {"four", "score", "seven", "and", "seven", "years", "ago", "far", "away"} // 
  RandomSample;
StringCases["fourscoreandsevenyearsago", Alternatives @@ words] // Map[Capitalize]

Have to watch out for substring matches

StringCases["fourscoreandsevenyearsago", Alternatives @@ Prepend[words, "fours"]]
(* {"fours", "and", "seven", "years", "ago"} *)
POSTED BY: Rohit Namjoshi
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract