Sorting array of values and counting unique values occurrences

132
3
Thursday
Julia8
by
New Contributor

Hi All,

I am struggling with creating a block of code that would sort my array, count unique values, and return them in a text string.

For example: I have this array of fruits:

["Apples", "Bananas", "Berry", "Bananas", "Apples", "Bananas"]

What I would like to get is this output:

Apples x 2, Bananas x 3, Berry x 1

 

I'm not sure how to get around to this, if it was Feature Set I would use the GroupBy function... 

Tags (3)
0 Kudos
3 Replies
MikeMillerGIS
Esri Frequent Contributor

What language?  In python, you can use a Counter

from collections import Counter
x = Counter(["Apples", "Bananas", "Berry", "Bananas", "Apples", "Bananas"])
print(x)
TimWestern
MVP

In JavaScript/Typescript you might take advantage of the reduce method (granted that 1 liner in python is freaking cool @MikeMillerGIS 

Here are two possibilities, one uses an NPM library called lodash the other looks is plain JS/Typescript (no new library needed to install)

JavaScript/Typescript using NPM library lodash  (the _ is the import name for lodash in this case)

import _ from "lodash";

function summarizeArray(arr: string[]): string {
  // Step 1: Count occurrences using _.countBy
  const counts = _.countBy(arr);

  // Step 2: Sort keys alphabetically and format the result
  const summary = _(counts)
    .toPairs() // Convert object to array of [key, value] pairs
    .sortBy(0) // Sort by the key (fruit name)
    .map(([fruit, count]) => `${fruit} x ${count}`) // Format each pair
    .join(", "); // Join into a single string

  return summary;
}

// Example usage
const fruits = ["Apples", "Bananas", "Berry", "Bananas", "Apples", "Bananas"];
const result = summarizeArray(fruits);
console.log(result); // Output: "Apples x 2, Bananas x 3, Berry x 1"


JavaScript/TypeScript with no additional library needed

function summarizeArray(arr: string[]): string {
  // Step 1: Count occurrences of each item
  const counts = arr.reduce((acc, fruit) => {
    acc[fruit] = (acc[fruit] || 0) + 1;
    return acc;
  }, {} as Record<string, number>);

  // Step 2: Sort the keys alphabetically
  const sortedKeys = Object.keys(counts).sort();

  // Step 3: Map to the desired format
  const summary = sortedKeys.map(key => `${key} x ${counts[key]}`).join(", ");

  return summary;
}

// Example usage
const fruits = ["Apples", "Bananas", "Berry", "Bananas", "Apples", "Bananas"];
const result = summarizeArray(fruits);
console.log(result); // Output: "Apples x 2, Bananas x 3, Berry x 1"

 

0 Kudos
DanPatterson
MVP Esteemed Contributor

not to leave numpy out

a = ["Apples", "Bananas", "Berry", "Bananas", "Apples", "Bananas"]

import numpy as np
def uniq(a):
    """`a` is your array."""
    u, cnts = np.unique(a, return_counts=True)
    st = ""
    for cnt, v in enumerate(u):
        st += "{}, {}  ".format(v, cnts[cnt])
    return st.strip()
    

uniq(a)
'Apples, 2  Bananas, 3  Berry, 1'

... sort of retired...