Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I ran my code through SonarQube and it suggested me to reduce my code's cognitive complexity. I make use of quite a few nested loops, but I have tried to reduce it to the best of my abilities and would appreciate some suggestions. According to sonarqube I can reduce the complexity by at least two two levels.

I've commented the code and will post it below. The first snippet is the model that the function pulls from:

Go
package model

    type PrefilterEntry struct {
        CustomerId string   `bson:"customer_id"`
        Timestamp  string   `bson:"timestamp"`
        Prefilters []uint64 `bson:"prefilters"`
    }

    type Uint64Slice []uint64

    func (p Uint64Slice) Len() int { return len(p) }

    func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] }

    func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

This is the function in question:

Go
func (s *service) checkMinimumPreFilters(ctx context.Context, uniquePrefilters []uint64, entries []model.PrefilterEntry, matchesNeeded float64) ([]string, error) {
    if len(entries) == 0 {
        err := errors.New("length of entries must be greater than 0")
        s.logger.Error(ctx, "insufficient prefilters: ", err)
        return []string{}, err
    }

    var customersMatched []string
    for _, v := range entries {

        // sort pre filters
        sort.Sort(model.Uint64Slice(v.Prefilters))

        preFilterMatches := 0
        for _, j := range v.Prefilters {

            for _, k := range uniquePrefilters {

                // both are sorted
                if k > j {
                    break
                }

                if j == k {
                    preFilterMatches++
                }

            }
        }

        if float64(preFilterMatches) >= matchesNeeded {
            customersMatched = append(customersMatched, v.CustomerId)
        }
    }

    return customersMatched, nil
}


What I have tried:

I've tried reduce the complexity down to the best of my abilities, but I can't seem to keep it less than three nested loops.

Any suggestions would be greatly appreciated.
Posted
Updated 4-May-22 8:55am
v2
Comments
Greg Utas 4-May-22 15:22pm    
If three nested loops are needed, why worry about it? There isn't much happening within each loop. Tools that generate metrics are hardly infallible.

That said, I don't know Go--which means that your code isn't "commented". If it was, I'd know what it was trying to do and might even be able to offer a useful suggestion. There are two brief comments, neither of which does much to explain the code. You're looking for matches in customer data using filters, and this requires a sort for some reason.
0x01AA 5-May-22 9:43am    
For me this is the solution ;)

if k > j
{
   break
}
[no name] 6-May-22 12:22pm    
It's the equivalent of "for each k in j" or "j in k"; whichever list is longer being the "IN" list. One for loop.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900