DataTypes icon indicating copy to clipboard operation
DataTypes copied to clipboard

Null type checks is not considered by the tests length

Open ghost opened this issue 6 years ago • 3 comments

There is a problem with countTypesInArray function (4-count-types.js). The tests require a solution to be 200 signs max, but in this case, we kinda lose the check for nulls.

As you know null in JavaScript has a type of object. Thus, the implementation you require will count objects but not nulls. So, the function is not suitable for checking all the JS types.

I clearly understand that such a check can be done using a ternary operator but it's not convenient and intuitive enough.

The implementation below considers this JS's quirk:

const data = [
  false,
  'a',
  22,
  'hey',
  undefined,
  42,
  12,
  true,
  { a: 12 },
  { name: 'Jack' },
  'foo',
  'bar',
  true,
  null,
  undefined,
  Symbol('a'),
  null
];

const countTypesInArray = data => {
  const h = {};
  for (const item of data) {
    if (typeof item === 'object' && item === null) {
      h['null'] = 1;

      if (h['null'] > 0) {
        h['null']++;
      }
    } else if (typeof item in h) {
      h[typeof item]++;
    } else {
      h[typeof item] = 1;
    }
  }
  return h;
};

console.log(countTypesInArray(data));

So, maybe you should consider an option for making tests a little bit more loose for null checks.

ghost avatar Sep 15 '19 18:09 ghost

See my example

const getKey = value => (value === null ? 'null' : typeof value);
/*
const getKey = value => {
  if (value === null) return 'null';
  return typeof value;
}
*/

const countTypesInArray = data => {
  const hash = {};
  for (const item of data) {
    const key = getKey(item);
    if (hash[key]) hash[key] += 1;
    else hash[key] = 1;
  }
  return hash;
};

PavelZubkov avatar Sep 15 '19 22:09 PavelZubkov

if (typeof item === 'object' && item === null) {
  h['null'] = 1;

  if (h['null'] > 0) {
    h['null']++;
  }

Test it on input data const data = [ null ];

PavelZubkov avatar Sep 15 '19 22:09 PavelZubkov

@PavelZubkov your solution seems to work just fine.

Regarding my function: yeah, you're right, that's my bad. I haven't mentioned the case when arr consists of only 1 null. But I still didn't find a better solution that won't use a ternary operator. The following one in some terms is the same as yours:

const countTypesInArray = arr => {
  const types = [];
  const hashTable = {};
  const type = typeof i;

  arr.forEach(item => {
    type === 'object' && item === null ? types.push('null') : types.push(type);
  });

  types.forEach(value => {
    value in hashTable ? hashTable[value]++ : hashTable[value] = 1;
  });

  return hashTable;
};

However, I've decided to make a new array and only after that perform counting of types. I think that on big amounts of data it'll perform slower, but it's simpler to read (IMO).

ghost avatar Sep 16 '19 19:09 ghost