github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/commons/container/trees/convert.go (about) 1 /* 2 * Copyright 2023 Wang Min Xiang 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 package trees 19 20 import ( 21 "github.com/aacfactory/errors" 22 "sort" 23 ) 24 25 const ( 26 treeTag = "tree" 27 ) 28 29 func ConvertListToTree[T any](items []T) (v []T, err error) { 30 itemLen := len(items) 31 if itemLen == 0 { 32 return 33 } 34 elements := make(Elements[T], 0, itemLen) 35 for _, item := range items { 36 element, elementErr := NewElement[T](item) 37 if elementErr != nil { 38 err = errors.Warning("fns: convert list to tree failed").WithCause(elementErr) 39 return 40 } 41 elements = append(elements, element) 42 } 43 for _, element := range elements { 44 convert[T](element, elements) 45 } 46 sort.Sort(elements) 47 for _, element := range elements { 48 if element.hasParent { 49 continue 50 } 51 v = append(v, element.Interface()) 52 } 53 return 54 } 55 56 func convert[T any](element *Element[T], elements Elements[T]) { 57 n := 0 58 for i, other := range elements { 59 if element.ident().Equal(other.parent()) { 60 convert[T](other, elements) 61 if !element.contains(other) { 62 element.children = append(element.children, other) 63 } 64 other.hasParent = true 65 elements[i] = other 66 n++ 67 } 68 } 69 if n > 0 { 70 sort.Sort(element.children) 71 } 72 }