Brace expansion using ranges: Difference between revisions
Content added Content deleted
(→{{header|Wren}}: Added two more examples.) |
(Added Go) |
||
Line 108: | Line 108: | ||
:* [[Range_expansion]] |
:* [[Range_expansion]] |
||
<br><br> |
<br><br> |
||
=={{header|Go}}== |
|||
{{trans|Wren}} |
|||
<lang go>package main |
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
"strings" |
|||
"unicode/utf8" |
|||
) |
|||
func parseRange(r string) []string { |
|||
if r == "" { |
|||
return []string{"{}"} // rangeless, empty |
|||
} |
|||
sp := strings.Split(r, "..") |
|||
if len(sp) == 1 { |
|||
return []string{"{" + r + "}"} // rangeless, random value |
|||
} |
|||
sta := sp[0] |
|||
end := sp[1] |
|||
inc := "1" |
|||
if len(sp) > 2 { |
|||
inc = sp[2] |
|||
} |
|||
n1, ok1 := strconv.Atoi(sta) |
|||
n2, ok2 := strconv.Atoi(end) |
|||
n3, ok3 := strconv.Atoi(inc) |
|||
if ok3 != nil { |
|||
return []string{"{" + r + "}"} // increment isn't a number |
|||
} |
|||
numeric := (ok1 == nil) && (ok2 == nil) |
|||
if !numeric { |
|||
if (ok1 == nil && ok2 != nil) || (ok1 != nil && ok2 == nil) { |
|||
return []string{"{" + r + "}"} // mixed numeric/alpha not expanded |
|||
} |
|||
if utf8.RuneCountInString(sta) != 1 || utf8.RuneCountInString(end) != 1 { |
|||
return []string{"{" + r + "}"} // start/end are not both single alpha |
|||
} |
|||
n1 = int(([]rune(sta))[0]) |
|||
n2 = int(([]rune(end))[0]) |
|||
} |
|||
width := 1 |
|||
if numeric { |
|||
if len(sta) < len(end) { |
|||
width = len(end) |
|||
} else { |
|||
width = len(sta) |
|||
} |
|||
} |
|||
if n3 == 0 { // zero increment |
|||
if numeric { |
|||
return []string{fmt.Sprintf("%0*d", width, n1)} |
|||
} else { |
|||
return []string{sta} |
|||
} |
|||
} |
|||
var res []string |
|||
asc := n1 < n2 |
|||
if n3 < 0 { |
|||
asc = !asc |
|||
n1, n2 = n2, n1 |
|||
n3 = -n3 |
|||
} |
|||
i := n1 |
|||
if asc { |
|||
for ; i <= n2; i += n3 { |
|||
if numeric { |
|||
res = append(res, fmt.Sprintf("%0*d", width, i)) |
|||
} else { |
|||
res = append(res, string(rune(i))) |
|||
} |
|||
} |
|||
} else { |
|||
for ; i >= n2; i -= n3 { |
|||
if numeric { |
|||
res = append(res, fmt.Sprintf("%0*d", width, i)) |
|||
} else { |
|||
res = append(res, string(rune(i))) |
|||
} |
|||
} |
|||
} |
|||
return res |
|||
} |
|||
func rangeExpand(s string) []string { |
|||
res := []string{""} |
|||
rng := "" |
|||
inRng := false |
|||
for _, c := range s { |
|||
if c == '{' && !inRng { |
|||
inRng = true |
|||
rng = "" |
|||
} else if c == '}' && inRng { |
|||
rngRes := parseRange(rng) |
|||
rngLen := len(rngRes) |
|||
var res2 []string |
|||
for i := 0; i < len(res); i++ { |
|||
for j := 0; j < rngLen; j++ { |
|||
res2 = append(res2, res[i]+rngRes[j]) |
|||
} |
|||
} |
|||
res = res2 |
|||
inRng = false |
|||
} else if inRng { |
|||
rng += string(c) |
|||
} else { |
|||
for i := 0; i < len(res); i++ { |
|||
res[i] += string(c) |
|||
} |
|||
} |
|||
} |
|||
if inRng { |
|||
for i := 0; i < len(res); i++ { |
|||
res[i] += "{" + rng // unmatched braces |
|||
} |
|||
} |
|||
return res |
|||
} |
|||
func main() { |
|||
examples := []string{ |
|||
"simpleNumberRising{1..3}.txt", |
|||
"simpleAlphaDescending-{Z..X}.txt", |
|||
"steppedDownAndPadded-{10..00..5}.txt", |
|||
"minusSignFlipsSequence {030..20..-5}.txt", |
|||
"combined-{Q..P}{2..1}.txt", |
|||
"emoji{🌵..🌶}{🌽..🌾}etc", |
|||
"li{teral", |
|||
"rangeless{}empty", |
|||
"rangeless{random}string", |
|||
"mixedNumberAlpha{5..k}", |
|||
"steppedAlphaRising{P..Z..2}.txt", |
|||
"stops after endpoint-{02..10..3}.txt", |
|||
} |
|||
for _, s := range examples { |
|||
fmt.Print(s, "->\n ") |
|||
res := rangeExpand(s) |
|||
fmt.Println(strings.Join(res, "\n ")) |
|||
fmt.Println() |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
Same as Wren entry. |
|||
</pre> |
|||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |