1// Copyright 2020 Jebbs. All rights reserved.
2// Use of this source code is governed by MIT
3// license that can be found in the LICENSE file.
4
5package rule
6
7import "github.com/qjebbs/go-jsons/merge"
8
9func mergeByFields(s []interface{}, fields []Field) ([]interface{}, error) {
10 if len(s) == 0 || len(fields) == 0 {
11 return s, nil
12 }
13 // from: [a,"",b,"",a,"",b,""]
14 // to: [a,"",b,"",merged,"",merged,""]
15 merged := &struct{}{}
16 for i, item1 := range s {
17 map1, ok := item1.(map[string]interface{})
18 if !ok {
19 continue
20 }
21 tags1 := getTags(map1, fields)
22 if len(tags1) == 0 {
23 continue
24 }
25 for j := i + 1; j < len(s); j++ {
26 map2, ok := s[j].(map[string]interface{})
27 if !ok {
28 continue
29 }
30 tags2 := getTags(map2, fields)
31 if !matchTags(tags1, tags2) {
32 continue
33 }
34 s[j] = merged
35 err := merge.Maps(map1, map2)
36 if err != nil {
37 return nil, err
38 }
39 }
40 }
41 // remove merged
42 ns := make([]interface{}, 0)
43 for _, item := range s {
44 if item == merged {
45 continue
46 }
47 ns = append(ns, item)
48 }
49 return ns, nil
50}
51
52func matchTags(a, b []string) bool {
53 for _, tag1 := range a {
54 for _, tag2 := range b {
55 if tag1 == tag2 {
56 return true
57 }
58 }
59 }
60 return false
61}
62
63func getTags(v map[string]interface{}, fields []Field) []string {
64 tags := make([]string, 0, len(fields))
65 for _, field := range fields {
66 value, ok := v[field.Key]
67 if !ok {
68 continue
69 }
70 if tag, ok := value.(string); ok && tag != "" {
71 tags = append(tags, tag)
72 }
73 }
74 return tags
75}