gitee.com/mysnapcore/mysnapd@v0.1.0/strutil/intersection.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2021 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package strutil 21 22 // Intersection computes the intersection of a set of slices, treating each 23 // slice as a set. It does not mutate any of the input slices and returns a new 24 // slice. It is recursive. 25 func Intersection(slices ...[]string) []string { 26 // handle trivial cases 27 switch len(slices) { 28 case 0: 29 return nil 30 case 1: 31 return slices[0] 32 case 2: 33 // actually perform the intersection 34 l1 := slices[0] 35 l2 := slices[1] 36 guessLen := len(l1) 37 if len(l1) > len(l2) { 38 guessLen = len(l2) 39 } 40 alreadyAdded := map[string]bool{} 41 result := make([]string, 0, guessLen) 42 for _, item := range l1 { 43 if !alreadyAdded[item] && ListContains(l2, item) { 44 result = append(result, item) 45 alreadyAdded[item] = true 46 } 47 } 48 return result 49 } 50 51 // all other cases require some recursion operating on smaller chunks 52 53 // we take advantage of the fact that intersection is commutative and 54 // iteratively perform an intersection between a running intersection of 55 // all previous lists and the next list in the total set of slices 56 57 // TODO: this could be sped up with maps or any number of things, but 58 // hopefully this is only ever used on a few lists that are small in size 59 // so we can get away with this inefficient implementation 60 result := slices[0] 61 for _, s := range slices[1:] { 62 result = Intersection(result, s) 63 } 64 return result 65 }