RRR uzumaki
RRR uzumaki

Reputation: 1328

Looping through and getting frequency of all the elements in an array

I am looping through an array which is [2,2,"2","2",4,4] so i am calulating frequency of each elements here and then storing the element as key in object and its frequency as a value of that corresponding key.

So below is the code for that

let countobjet={},r=[]
for(i=0;i<array.length;i++){
  let count=0

  for(j=0;j<array.length;j++){
    if(array[i]===array[j]){count++ 

  }
  }
countobjet[array[i]]=count
}
console.log(countobjet)

Now console.log here gives

{2: 2, 4: 2}

what i want was

{2:2,2:2,4:2}

as i have two "2" of type string and two 2 of type number, i want to treat them as seperate key in the object cause i have to calulate its frequency seperately considering their type

Upvotes: 0

Views: 115

Answers (4)

VLAZ
VLAZ

Reputation: 28983

You can't really do this with an object, since all keys of objects either strings or symbols. A non-string or non-symbol key would be converted to a string instead:

const obj = {};

obj["42"] = 1;
obj[42] = 2;

console.log(obj)

If you want to keep the type intact, you can use a Map which does not have this limitation for its keys:

const array = [2,2,"2","2",4,4];

let countobjet = new Map(),
  r = []
for (i = 0; i < array.length; i++) {
  let count = 0

  for (j = 0; j < array.length; j++) {
    if (array[i] === array[j]) {
      count++
    }
  }
  countobjet.set(array[i], count)
}

for(let [key, value] of countobjet.entries()) {
  console.log(`For key ${key} of type ${typeof key}, count is: ${value}`)
}

console.log(Array.from(countobjet.entries()));

Upvotes: 3

Kevin
Kevin

Reputation: 451

You should use a Map instead of an object. Objects coerce keys into strings. Maps can use objects or primitives.

const frequencies = arr =>
  arr.reduce((m, e) => m.set(e, (m.get(e) || 0) + 1), new Map())

const data = [2, 2, '2', '2', 4, 4]

const result = frequencies(data)

console.log(result) // Map { 2 => 2, '2' => 2, 4 => 2 }

If you have to use an object you could do something like the next two examples.

You can make a key by combining type and value:

const key = x => `${typeof x} ${x}`

const frequencies = arr =>
  arr.reduce(
    (o, e) => ({
      ...o,
      [key(e)]: (o[key(e)] || 0) + 1,
    }),
    {}
  )

const data = [2, 2, '2', '2', 4, 4]

const result = frequencies(data)

console.log(result)

Or, nest the frequency counts in type properties:

const frequencies = arr =>
  arr.reduce((o, e) => {
    const type = typeof e
    o[type] = o[type] || {}
    o[type][e] = (o[type][e] || 0) + 1
    return o
  }, {})

const data = [2, 2, '2', '2', 4, 4]

const result = frequencies(data)

console.log(result)

Upvotes: 2

abnaceur
abnaceur

Reputation: 262

As the key is "2" it will be overridden for the occurrences on String and number.

You can check the occurrences as follow

let countobjet = {};
let array = [2, 2, "2", "2", 4, 4];

for (i = 0; i < array.length; i++) {
    let count = 0

    for (j = 0; j < array.length; j++) {
        if (typeof array[i] === 'string' && typeof array[j] === 'string'
            && array[i] === array[j]) {
            count++;
        } else if (typeof array[i] === 'number' && typeof array[j] === 'number'
            && array[i] === array[j]) {
            count++;
        }
    }
    if (typeof array[i] === 'string')
        countobjet[array[i] + '_str'] = count;
    else
        countobjet[array[i]] = count;
}
console.log(countobjet)

enter image description here

Upvotes: 1

Ryker
Ryker

Reputation: 802

The Object keys in javascript behave like "strings". Also, in an object two keys cannot be the same.

This is the reason why your code is not working.

In object literal terms, b is a property. Properties are either strings or symbols in JavaScript, although when defining the property name inside an object literal you may omit the string delimiters.

for (key in a) {
    alert(typeof key);
    //-> "string"
}

Upvotes: 2

Related Questions