// Here is another implementation of flatten, that uses the JSON
// unmarshaler in the standard library. Used to compare against the
// flattener in this package to increase confidence in correctness.
// It's faster too, of course. It requires the whole input though, so
// would not work well in a pipeline.
Here is another implementation of flatten, that uses the JSON
unmarshaler in the standard library. Used to compare against the
flattener in this package to increase confidence in correctness.
It's faster too, of course. It requires the whole input though, so
would not work well in a pipeline.
// Here is another implementation of flatten that uses the JSON // unmarshaler in the standard library . Used to compare against the // flattener in this package to increase confidence in correctness . // It ' s faster too of course . It requires the whole input though so // would not work well in a pipeline .
func stdlibFlatten(input []byte) (pairs []pair) {
	join := func(path, elem string) string {
		if path == "." {
			return path + elem
		}
		return path + "." + elem
	}
	var flattenRecursively func(obj interface{}, path string)
	flattenRecursively = func(obj interface{}, path string) {
		switch v := obj.(type) {
		case nil:
			pairs = append(pairs, pair{path: path, value: "null"})
		case bool:
			pairs = append(pairs, pair{path: path, value: fmt.Sprintf("%t", v)})
		case float64:
			pairs = append(pairs, pair{path: path, value: fmt.Sprintf("%f", v)})
		case string:
			pairs = append(pairs, pair{path: path, value: fmt.Sprintf("%q", v)})
		case map[string]interface{}:
			pairs = append(pairs, pair{path: path, value: `{}`})
			for key, obj := range v {
				flattenRecursively(obj, join(path, fmt.Sprintf("%q", key)))
			}
		case []interface{}:
			pairs = append(pairs, pair{path: path, value: `[]`})
			for i, obj := range v {
				flattenRecursively(obj, path+fmt.Sprintf("[%d]", i))
			}
		default:
			panic(fmt.Sprintf("unhandled input: %v", obj))
		}
	}
	var obj interface{}
	if err := json.Unmarshal(input, &obj); err != nil {
		pairs = append(pairs, pair{err: err})
		return
	}
	flattenRecursively(obj, ".")
	return
}
func stdlibFlatten ( input [ ] byte ) ( pairs [ ] pair ) { join := func ( path , elem string ) string { if path == " " { return path + elem } return path + " " + elem } var flattenRecursively func ( obj interface { } , path string ) flattenRecursively = func ( obj interface { } , path string ) { switch v := obj . ( type ) { case nil : pairs = append ( pairs , pair { path : path , value : " " } ) case bool : pairs = append ( pairs , pair { path : path , value : fmt . Sprintf ( " " , v ) } ) case float64 : pairs = append ( pairs , pair { path : path , value : fmt . Sprintf ( " " , v ) } ) case string : pairs = append ( pairs , pair { path : path , value : fmt . Sprintf ( " " , v ) } ) case map [ string ] interface { } : pairs = append ( pairs , pair { path : path , value : `{}` } ) for key , obj := range v { flattenRecursively ( obj , join ( path , fmt . Sprintf ( " " , key ) ) ) } case [ ] interface { } : pairs = append ( pairs , pair { path : path , value : `[]` } ) for i , obj := range v { flattenRecursively ( obj , path + fmt . Sprintf ( " " , i ) ) } default : panic ( fmt . Sprintf ( " " , obj ) ) } } var obj interface { } if err := json . Unmarshal ( input , & obj ) ; err != nil { pairs = append ( pairs , pair { err : err } ) return } flattenRecursively ( obj , " " ) return }
Here is another implementation of flatten, that uses the JSON
unmarshaler in the standard library.
Here is another implementation of flatten that uses the JSON unmarshaler in the standard library .