Решение на Нормализация на пътища от Андрей Радев

Обратно към всички решения

Към профила на Андрей Радев

Резултати

  • 10 точки от тестове
  • 0 бонус точки
  • 10 точки общо
  • 8 успешни тест(а)
  • 0 неуспешни тест(а)

Код

package main
import "strings"
func parsePath(path string) string {
components := []string{}
for _, component := range strings.Split(path, "/") {
if component == "" {
// Ignore, start/end slashes
} else if component == "." {
// Ignore, current directory
} else if component == ".." {
// Parent directory, one up if possible
if len(components) > 0 {
components = components[:len(components)-1]
}
} else {
// Just add it to the list
components = append(components, component)
}
}
if len(components) == 0 {
return "/"
} else {
return "/" + strings.Join(components, "/") + "/"
}
}

Лог от изпълнението

PASS
ok  	_/tmp/d20131015-29033-1bc7rql	0.011s
PASS
ok  	_/tmp/d20131015-29033-1bc7rql	0.011s
PASS
ok  	_/tmp/d20131015-29033-1bc7rql	0.011s
PASS
ok  	_/tmp/d20131015-29033-1bc7rql	0.011s
PASS
ok  	_/tmp/d20131015-29033-1bc7rql	0.011s
PASS
ok  	_/tmp/d20131015-29033-1bc7rql	0.011s
PASS
ok  	_/tmp/d20131015-29033-1bc7rql	0.011s
PASS
ok  	_/tmp/d20131015-29033-1bc7rql	0.013s

История (3 версии и 5 коментара)

Андрей обнови решението на 09.10.2013 00:32 (преди над 4 години)

+package main
+
+import "strings"
+
+func parsePath(path string) string {
+ components := []string{}
+
+ for _, component := range strings.Split(path, "/") {
+ if component == "" {
+ // Ignore, start/end slashes
+ } else if component == "." {
+ // Ignore, current directory
+ } else if component == ".." {
+ // Parent directory, one up if possible
+ if len(components) > 0 {
+ components = components[:len(components)-1]
+ }
+ } else {
+ // Just add it to the list
+ components = append(components, component)
+ }
+ }
+
+ if len(components) == 0 {
+ return "/"
+ } else {
+ return "/" + strings.Join(components, "/") + "/"
+ }
+}

Андрей обнови решението на 09.10.2013 00:34 (преди над 4 години)

package main
import "strings"
func parsePath(path string) string {
- components := []string{}
+ components := []string{}
- for _, component := range strings.Split(path, "/") {
- if component == "" {
- // Ignore, start/end slashes
- } else if component == "." {
- // Ignore, current directory
- } else if component == ".." {
- // Parent directory, one up if possible
- if len(components) > 0 {
- components = components[:len(components)-1]
- }
- } else {
- // Just add it to the list
- components = append(components, component)
- }
- }
+ for _, component := range strings.Split(path, "/") {
+ if component == "" {
+ // Ignore, start/end slashes
+ } else if component == "." {
+ // Ignore, current directory
+ } else if component == ".." {
+ // Parent directory, one up if possible
+ if len(components) > 0 {
+ components[len(components)-1] = ""
+ components = components[:len(components)-1]
+ }
+ } else {
+ // Just add it to the list
+ components = append(components, component)
+ }
+ }
- if len(components) == 0 {
- return "/"
+ if len(components) == 0 {
- } else {
+ return "/"
- return "/" + strings.Join(components, "/") + "/"
+ } else {
- }
+ return "/" + strings.Join(components, "/") + "/"
-}
+ }
+}

Това предположих, че ще го кажеш. Харесва ми от гледна точка на документация. Примерно, изобщо не би ми било очевидно защо се проверява за празен низ ако не съм имплементирал функцията. Чисто и просто имаш първата и последната /, които могат да ти генерират допълнителни елементи, но това е само очевидно, докато го пишеш. Празен низ по средата не би трябвало да се случи, даже не би било чудно да искаме да гръмнем в такъв случай с parsing error, щото не е валиден "път". Всичко това иска някаква мисъл, когато четеш кода и се опитваш да разбереш WTF прави.

Ти също го знаеш, защото си мислил за имплементация и знаеш какво прави, а и сега прочете коментара. Човек, който вижда имплементацията без да знае спецификацията и без да има коментар, който да го обясни, вероятно ще му отнеме малко главочесане да схване за къв чеп се филтрират "" и при какви условия може да ги има. В случая може би не е чак такъв проблем, но би могло да е като дебъгваш след 7 часа работа.

Но да кажем, че това си е моя inherent фанатизъм. Да ъпдейтна ли функцията (може би ще са публични и искаме админите да имат консистентни решения)?

А, да, относно memory leak-а.

a = a[1:]

Този код ти leak-ва. Убеден съм, че съм виждал потвърждение някъде, но не мога да се сетя къде. Идеята е, че ти преместваш a да сочи едно напред и вече изгубваш възможността да реферерираш към този нулев елемент. Ако го правиш в голямо цикълче, или е long-living object, си преебан.

В случая, всъщност няма leak, наистина бъркам. Просто защото не е първи, а последен елемент, така че пак можеш да си го реферираш. Нулирането просто го reset-ва, така че да се стигне до known state, нямам идея дали това е добре или не. Видях го някъде из нетя относно изтриване на елементи, но щом не е leak, в случая едва ли има проблем. Може би примерно ако вземеш raw pointer към масива, би било проблем. Ти какво мислиш, да drop-на ли нулирането на последния елемент?

Андрей обнови решението на 09.10.2013 14:51 (преди над 4 години)

package main
import "strings"
func parsePath(path string) string {
components := []string{}
for _, component := range strings.Split(path, "/") {
if component == "" {
// Ignore, start/end slashes
} else if component == "." {
// Ignore, current directory
} else if component == ".." {
// Parent directory, one up if possible
if len(components) > 0 {
- components[len(components)-1] = ""
components = components[:len(components)-1]
}
} else {
// Just add it to the list
components = append(components, component)
}
}
if len(components) == 0 {
return "/"
} else {
return "/" + strings.Join(components, "/") + "/"
}
}