Search code examples
iosswiftstringfrequencypercentage

I need help calculating the frequency and percentage, I need it in order of most frequent and without the quotation marks & curly brackets etc


I've been using a website to calculate the frequency up until now but they have a maximum of 50,000 characters and now I need to do it myself which is really what I should have done from the start.

   let frequencyCount = Dictionary(grouping: numbers) { $0 }
        .mapValues{ $0.count }

   mostFrequentTextView.text = String(format:"%@", frequencyCount)


   let numbers = [

    "1, 2, 3, 4",
    "5, 6, 7, 8",
    "3, 4, 5, 6",
    "1, 2, 7, 8",
    "1, 2, 3, 4",
    "3, 4, 5, 6",
    "1, 2, 3, 4",
    "1, 2, 3, 4",
    "5, 6, 7, 8",
    "3, 4, 5, 6",
    "1, 2, 7, 8",
    "1, 2, 3, 4",
    "3, 4, 5, 6",
    "1, 2, 3, 4" ]

//Current result ↓

          {
     "1, 2, 3, 4" = 6;
     "1, 2, 7, 8" = 2;
     "3, 4, 5, 6" = 4;
     "5, 6, 7, 8" = 2;
          }

//Desired result ↓

      1, 2, 3, 4   X 6   43%

      3, 4, 5, 6   X 4   29%

      1, 2, 7, 8   X 2   14%

      5, 6, 7, 8   X 2   14%

Solution

  • Once grouped then you can use sorted and reduce to build the output

    let output = frequencyCount.sorted(by: {$0.value > $1.value}).reduce(into: "") {
        let fraction =  Int(round(100.0 * Double($1.value) / Double(numbers.count)))
        $0 += "\($1.key)   X \($1.value)  \(fraction)%\n"
    }
    

    Output

    1, 2, 3, 4   X 6  43%  
    3, 4, 5, 6   X 4  29%  
    1, 2, 7, 8   X 2  14%  
    5, 6, 7, 8   X 2  14%
    

    If you prefer String.format()

    let fraction = round(100.0 * Double($1.value) / Double(numbers.count))
    $0 += String(format: "%@   X %d  %.0f%%\n", $1.key, $1.value, fraction)
    

    Complete code if you want to put everything together

    let total = Double(numbers.count)
    let output = Dictionary(grouping: numbers) { $0 }
        .mapValues{ $0.count }
        .sorted(by: {$0.value > $1.value})
        .reduce(into: "") {
            $0 += "\($1.key)   X \($1.value)  \(Int(round(100.0 * Double($1.value) / total)))%\n"
        }