user8560360
user8560360

Reputation:

How to get least frequent item of array - javascript?

I'm using the following function to get the most frequent item of an array:

Array.prototype.array_most_frequent = function()  {
  var m=0, mf=0;
  for (var i=0; i<this.length; i++) {
          for (var j=i; j<this.length; j++)
          {
            if (this[i] == this[j]) m++;
            if (mf<m) {mf=m; item = this[i]; }
          }
          m=0;
  }
  return item;
}

Works fine - but how to get the rarest item of an array?

For example var array=[2,1,2,5,5] should return '1'.

Is there an easy way to the least frequent item of my array?

Thanks in advance.

Upvotes: 1

Views: 4069

Answers (7)

Julio C.
Julio C.

Reputation: 65

The short solution could be this, if the sort function don't mutate the array, even passing the parameter by a function. (If passing for a class constructor this will not happen.)

Modifying a little bit... this.

const arr = [2, 1, 2, 5, 5];
const result = arr.sort((a,b) =>
          arr.filter(v => v===b).length
        - arr.filter(v => v===a).length
    ).pop();

console.log(result)

But sometimes mutability is not desired and that could be an inconvenient, so follow in bellow a solution with no mutability:

Based in a this solution, that just count and add for a object, the name of repeated value and how much times it happen. After that, just take the least one, search in object by the least value to return the name of key that least is repeated.

const arr = [2, 1, 2, 5, 5];
const reducedOnes = arr.reduce((acc, val) => ({...acc, [val]: (acc[val] || 0) + 1}), {});
const leastFrequency = Math.min(...Object.values(reducedOnes));
const leastItem = Object.keys(reducedOnes).find(el=>reducedOnes[el]===leastFrequency);

console.log(leastItem);

Upvotes: 1

Olena Stotska
Olena Stotska

Reputation: 1

const arr = [1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 4, 4]

function leastFrequent(items) {
  let leastFrequentNumber = items[0]
  const counted = items.reduce((acc, item) => { 
    if (!acc[item]) {
      acc[item] = 1
    } else {
      acc[item]++
    }

    if(acc[item] < acc[leastFrequentNumber]) {
      leastFrequentNumber = item
    }

    return acc;
  }, {});

  return leastFrequentNumber
}

console.log(leastFrequent(arr)) //3

Upvotes: 0

Faisal Sayed
Faisal Sayed

Reputation: 56

You can create a dictionary for counting the occurrences of array elements, and then return the key for the lowest count.

function rarestFromArray(arr) {
  // Create dictionary with array element as key and occurence count as value
  var arrMap = arr.reduce(function(obj, val) {
    obj[val] = ++obj[val] || 1;
    return obj;
  }, {});
  // Cache first element as the point of reference
  var rarest = Object.keys(arrMap)[0];

  // Compare and return the lowest count
  for (key in arrMap) {
    // gets first occurence of lowest count
    rarest = arrMap[rarest] > arrMap[key] ? key : rarest;

    // gets last occurence of lowest count
    // rarest = arrMap[rarest] < arrMap[key] ? rarest : key;
  }
  return rarest;
}

var inputArr = [1, 1, 1, 1, 2, 2, 2, 3, 33, 4, 4];
console.log(rarestFromArray(inputArr));

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 191976

An ES6 solution that creates a Map of occurrences using Array#reduce. Then spread the map to get the entries, and reduce the entry to the entry with the smallest number of occurrences:

const array=[2,1,2,5,5];

const result = [...array.reduce((r, n) => // create a map of occurrences
    r.set(n, (r.get(n) || 0) + 1), new Map()
  )]
  .reduce((r, v) => v[1] < r[1] ? v : r)[0]; // get the the item that appear less times


console.log(result);

Upvotes: 4

sandrooco
sandrooco

Reputation: 8716

ES6-way without unused iterating:

const getRarest = originalArray => {
    const temp = {};
    const counts = originalArray
      .map(item => {
         temp[item] = 0;
         return item;
      })
     .reduce((acc, item) => {
         acc[item]++;
         return acc;
     }, temp);

    const resultArray = Object.entries(counts).sort(
        ([key, val], [bKey, bVal]) => bVal < val
    );

    return (rarest = parseInt(resultArray[0][0]));
};

//Implementation
const arr = [3, 2, 4, 4];
console.log(getRarest(arr));

Upvotes: 0

Andrew Senner
Andrew Senner

Reputation: 2509

You could use a hash to track occurrences then return min value of its values.

function leastFrequent(arr) {
    var dict = {};
    arr.forEach(function(el) {
        if (!dict[el]) dict[el] = 0;
        dict[el]++;
    });
    return Math.min.apply(null, Object.values(dict));
}

// ES6+
const leastFrequent = arr => {
    const dict = {};
    arr.forEach(function(el) {
        if (!dict[el]) dict[el] = 0;
        dict[el]++;
    });
    return Math.min(...Object.values(dict));
}

Cheers

Upvotes: 1

Tarun
Tarun

Reputation: 3165

var arr = [2,1,2,5,5];
var frequencyMap = {};
for(var i=0; i<arr.length; i++) {
   frequencyMap[arr[i]] = frequencyMap[arr[i]] || 0;
   frequencyMap[arr[i]]++;
}
var maxValue = 0,maxFreq=0, minValue=NUMBER.MAX_INTEGER,minFreq=0;
for (var key in frequencyMap) {
    if (frequencyMap[key] > maxFreq){
       maxFreq  = frequencyMap[key];
       maxValue = key;
    }else if (frequencyMap[key] < minFreq){
       minFreq  = frequencyMap[key];
       minValue = key;
    }
}

Upvotes: 0

Related Questions