Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

each* string functions #91

Open
sagikazarmark opened this issue Apr 2, 2018 · 5 comments
Open

each* string functions #91

sagikazarmark opened this issue Apr 2, 2018 · 5 comments

Comments

@sagikazarmark
Copy link

Recently I needed to work with string slices in templates and apply various functions to each element (title, lower, trim, etc). I wanted to avoid using loops and assignments, so I came up with eachTitle, eachLower, eachTrim, etc functions.

It's quite simple really:

// each applies a function to each string in a slice.
func each(s []string, fn func(string) string) []string {
	for key, value := range s {
		s[key] = fn(value)
	}

	return s
}

// eachFunc makes a simple string transformation function to an each function.
func eachFunc(fn func(string) string) func([]string) []string {
	return func(s []string) []string {
		return each(s, fn)
	}
}

Usage:

funcMap["eachTitle"] = eachFunc(strings.Title)

Do you think it would fit into this package? I could extend it into a solution that would work with functions that have more than one parameter.

@helgi
Copy link
Contributor

helgi commented Jul 31, 2018

I think this could be useful, especially with multi-arg support. Would you see a version of this wherein the templates the user could simply do each "trim" <args> (trim just being an example, replace with whatever function) in addition to the each* you are suggesting

@sagikazarmark
Copy link
Author

I believe that would either require reflection or a big switch which would in turn call the actual function. It could work, but in my experience explicit function calls work better in this case. Since there is a pattern, it's really easy to guess the behavior.

But yeah, that could work.

@mattfarina
Copy link
Member

@sagikazarmark What would the template functions be, what would they work on, and why those things?

I'm trying to understand the end user need and what would be solved.

The technique looks interesting and I could see uses. Just trying to understand why and how to bake it in here. The why and what it solves is important.

@boosh
Copy link

boosh commented Dec 1, 2018

I came looking for something like this. Actually I wanted to runprintf over elements of a list. I've ended up having to implement my own mapPrintF function but it would have been much more convenient to have just been able to write e.g. {{ map "printf" "values-%s.yaml" .myList }} to return a list where each element has been modified by the printf function. In fact, functional constructs in general (map, reduce, filter, etc.) would be super handy...

@sagikazarmark
Copy link
Author

@mattfarina sorry, but I don't remember what the use case was.

I guess the idea is that you can output a list of strings, but apply some filters to it first? Unfortunately I rarely use templates these days. :\

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants