I got the below coding assessment question in Javascript. I tried my best to solve but there are few edge cases I missed. I need help with the solution.
Below are the steps I though of performing. I am still beginner learrning data structure and algo. I am not sure if below approach will work. I need help to solve this problem. Thanks
Question
Array of Types Sorting Your task it to write a function that takes an array containing values of different types and returns an object that lists all the different types grouped in respective sub-sections.
Examples
Types Input Output
Primitive types [ 1, "string", 2, true, false ] { number: [ 1, 2 ], string: [ "string" ], boolean: [ true, false ] }
Differrent Object Types [ {}, [], null ] { object: [ {} ], array: [ [] ], null: [ null ] }
Edge Cases Class instances do not need to be considered and can be treated as type object for this assignement.
const filterArray = () => {
// fill me with code
}
export default filterArray
Test
import filterArray from './solution'
describe('basic tests', () => {
test('strings', () => {
expect(filterArray(["a", "b", "c"])).toEqual({ string: ["a", "b", "c"] })
})
})```
My thought process for solving this
1.create new array that will be returned..
2.loop over given array...
3.check type if no: append "number: [1, 2]"
4.add more if else conditions for other types
const filterArray = (arr) => {
let result = {}
let str;
// other variables
for (const it of arr) {
switch (typeof it) {
case "string":
if (!str) {
str = []
result.string = str
}
str.push(it)
break;
// other cases
}
}
return result
}
Edited:
const filterArray = (arr) => {
// fill me with code
let result = {};
let str;
let num;
let bool;
let obj;
let arrX;
let n;
let u;
// other variables
for (const it of arr) {
switch (typeof it) {
case 'string':
if (!str) {
str = [];
result.string = str;
}
str.push(it);
break;
case 'number':
if (!num) {
num = [];
result.number = num;
}
num.push(it);
break;
case 'boolean':
if (!bool) {
bool = [];
result.boolean = bool;
}
bool.push(it);
break;
case 'object':
if (it instanceof Array) {
if (!arrX) {
arrX = [];
result.array = arrX;
}
arrX.push(it);
} else if (it === null) {
if (!n) {
n = [];
result.null = n;
}
n.push(it);
} else {
if (!obj) {
obj = [];
result.object = obj;
}
obj.push(it);
}
break;
case 'undefined':
if (!u) {
u = [];
result.undefined = u;
}
u.push(it);
break;
}
}
console.log(result);
return result;
};
Also, use partial object equality to test the object:
describe('filter test', () => {
test('should specifiy types', () => {
const filtered = filterArray([{}, [], null]);
expect(filtered).toEqual(
expect.objectContaining({
object: expect.arrayContaining([expect.objectContaining({})]),
array: expect.arrayContaining([expect.arrayContaining([])]),
null: expect.arrayContaining([null]),
})
);
});
});
@dharmisha Delete this too you forgot I believe
You can solve it using Array.prototype.reduce().
Make sure you understand the code below; do not simply copy&paste it.
const func1 = () => {};
const func2 = () => {};
const input = [1, 2, 3.75, 'a', 'b', 'c', {}, { foo: 'bar' }, [], ['foo', 'bar'], null, null, undefined, null, true, false, func1, func2, NaN, NaN, 5 / 0, 0 / 5];
const output = input.reduce((outObj, item) => {
// check the type of the item
let itemType = typeof item;
// if the item is of type 'number' you might want to discriminate
// between actual numbers and `NaN` (Not-a-Number)
if (itemType === 'number' && isNaN(item)) itemType = 'nan';
// if the item is of type 'object' you will have to further check
// whether it is `null`, an array, or an actual object
if (itemType === 'object') {
if (item === null) itemType = 'null';
if (Array.isArray(item)) itemType = 'array';
}
// if the output object already contains a key for the item type
// add the item to that key otherwise
// create the output object new type key and add the item to it
outObj[itemType] = outObj[itemType] ? [...outObj[itemType], item] : [item];
// return the output object
return outObj;
}, {});
// test
console.log(output)
[edit]
The code block:
let itemType = typeof item;
if (itemType === 'number' && isNaN(item)) itemType = 'nan';
if (itemType === 'object') {
if (item === null) itemType = 'null';
if (Array.isArray(item)) itemType = 'array';
}
can be written as:
let itemType = typeof item;
if (item === null) {
itemType = 'null';
} else if (itemType === 'object' && Array.isArray(item)) {
itemType = 'array';
} else if (itemType === 'number' && isNaN(item)) {
itemType = 'nan';
}
or
const itemType = item === null
? 'null'
: Array.isArray(item)
? 'array'
: typeof item === 'number' && isNaN(item)
? 'nan'
: typeof item
or
const itemType = (item === null && 'null') ||
(Array.isArray(item) && 'array') ||
(typeof item === 'number' && isNaN(item) && 'nan') ||
typeof item
IMVHO, the first code block illustrates a bit better the "human" reasoning (and plays better with the comments interpolation) therefore it is acceptable for explaining the logic, but it is unlikely you will find code written like that in a real case scenario.