ExtractLevels returns a new Splits that only has the given levels of indexes, in their given order, with the other levels removed and their corresponding indexes merged into the appropriate remaining levels. Any existing aggregation data is not retained in the new splits.
(levels []int)
| 225 | // merged into the appropriate remaining levels. |
| 226 | // Any existing aggregation data is not retained in the new splits. |
| 227 | func (spl *Splits) ExtractLevels(levels []int) (*Splits, error) { |
| 228 | nlv := len(levels) |
| 229 | if nlv == 0 || nlv >= len(spl.Levels) { |
| 230 | return nil, fmt.Errorf("table.Splits ExtractLevels: levels length == 0 or >= Levels") |
| 231 | } |
| 232 | aggs := spl.Aggs |
| 233 | spl.Aggs = nil |
| 234 | ss := spl.Clone() |
| 235 | spl.Aggs = aggs |
| 236 | ss.SortOrder(levels) |
| 237 | // now just do the grouping by levels values |
| 238 | lstValues := make([]string, nlv) |
| 239 | curValues := make([]string, nlv) |
| 240 | var curIx *IndexView |
| 241 | nsp := len(ss.Splits) |
| 242 | for si := nsp - 1; si >= 0; si-- { |
| 243 | diff := false |
| 244 | for li := range levels { |
| 245 | vl := ss.Values[si][levels[li]] |
| 246 | curValues[li] = vl |
| 247 | if vl != lstValues[li] { |
| 248 | diff = true |
| 249 | } |
| 250 | } |
| 251 | if diff || curIx == nil { |
| 252 | curIx = ss.Splits[si] |
| 253 | copy(lstValues, curValues) |
| 254 | ss.Values[si] = slices.Clone(curValues) |
| 255 | } else { |
| 256 | curIx.Indexes = append(curIx.Indexes, ss.Splits[si].Indexes...) // absorb |
| 257 | ss.Delete(si) |
| 258 | } |
| 259 | } |
| 260 | ss.Levels = make([]string, nlv) |
| 261 | for li := range levels { |
| 262 | ss.Levels[li] = spl.Levels[levels[li]] |
| 263 | } |
| 264 | return ss, nil |
| 265 | } |
| 266 | |
| 267 | // Clone returns a cloned copy of our SplitAgg |
| 268 | func (sa *SplitAgg) Clone() *SplitAgg { |