Github: JavaScript Problems by Mitchell
Group By
Write code that enhances all arrays such that you can call the
array.groupBy(fn)
method on any array and it will return a grouped version of the array.A grouped array is an object where each key is the output of
fn(arr[i])
and each value is an array containing all items in the original array with that key.The provided callback
fn
will accept an item in the array and return a string key.The order of each value list should be the order the items appear in the array. Any order of keys is acceptable.
Please solve it without lodash's
_.groupBy
function. - LeetCode
Solutions
Creates an object where each key is derived from applying the iteratee function to the elements of the array. The corresponding value for each key is an array of elements that produce the same key when passed through the iteratee function.
Code
TypeScript
export default function groupBy<T>(
array: Array<T>,
iteratee: (value: T) => number | string,
): Record<string, Array<T>> {
const result: Record<string, Array<T>> = Object.create(null);
for (const element of array) {
const key = iteratee(element);
result[key] ??= [];
result[key].push(element);
}
return result;
}
Array Wrapper
Create a class
ArrayWrapper
that accepts an array of integers in its constructor. This class should have two features:
When two instances of this class are added together with the
+
operator, the resulting value is the sum of all the elements in both arrays.When the
String()
function is called on the instance, it will return a comma separated string surrounded by brackets. For example,[1,2,3]
Solutions
Implement the .valueOf
and .toString
methods.
Code
TypeScript
class ArrayWrapper {
private _nums: number[];
constructor(nums: number[]) {
this._nums = nums;
}
valueOf(): number {
return this._nums.reduce((sum, num) => sum + num, 0);
}
toString(): string {
return `[${this._nums.join(',')}]`;
}
};
Flatten
Given a multi-dimensional array
arr
and a depthn
, return a flattened version of that array.A multi-dimensional array is a recursive data structure that contains integers or other multi-dimensional arrays.
A flattened array is a version of that array with some or all of the sub-arrays removed and replaced with the actual elements in that sub-array. This flattening operation should only be done if the current depth of nesting is less than
n
. The depth of the elements in the first array are considered to be0
.Please solve it without the built-in
Array.flat
method. - LeetCode
Solutions
Iterates over each element of the input array.
For each element:
If the element is an array and the depth
n
is not zero, the function recursively flattens this element by calling itself with the depth decreased by one (n - 1
). The result of this recursive call is then added to theresult
array.If the element is not an array, or if the depth
n
is zero, the element is directly added to theresult
array.
Code
TypeScript
type MultiDimensionalArray = (number | MultiDimensionalArray)[];
const flat = function (arr: MultiDimensionalArray, n: number): MultiDimensionalArray {
const result = [];
for (const item of arr) {
if (Array.isArray(item) && n !== 0) {
result.push(...flat(item, n - 1));
} else {
result.push(item);
}
}
return result;
};
remove duplicates
Given an array containing all kinds of data, please implement a function
deduplicate()
to remove the duplicates.You should modify the array in place. Order doesn't matter.
Solutions
Sort the array first, then using two points to compare.
Code
TypeScript
const removeDuplicate = (arr) => {
arr.sort();
let i = 0;
for (let j = 1; j < arr.length; j++) {
if (arr[i] !== arr[j]) {
i++;
arr[i] = arr[j];
}
}
arr.splice(i + 1);
}
Array-like to array
Convert array-like object to array.
Solutions
There are multiple solutions, the easiest one is using Array.from().
Code
TypeScript
Array.from(document.querySelectorAll('div'));
Chunk
Given an array
arr
and a chunk sizesize
, return a chunked array.A chunked array contains the original elements in
arr
, but consists of subarrays each of lengthsize
. The length of the last subarray may be less thansize
ifarr.length
is not evenly divisible bysize
.You may assume the array is the output of
JSON.parse
. In other words, it is valid JSON.Please solve it without using lodash's
_.chunk
function. - LeetCode
Solutions
If the input is not a valid array or if the size is less than 1, returns an empty array. Iterates through the input array, adding elements to a temporary chunk array. When the chunk reaches the specified size or the end of the input array is reached, the chunk is added to the result array, and a new chunk is started.
Code
TypeScript
export default function chunk<T>(array: Array<T>, size = 1): Array<Array<T>> {
if (!Array.isArray(array) || size < 1) {
return [];
}
const result = [];
let chunk = [];
for (let i = 0; i < array.length; i++) {
chunk.push(array[i]);
if (chunk.length === size || i === array.length - 1) {
result.push(chunk);
chunk = [];
}
}
return result;
}
Compact Object
Given an object or array
obj
, return a compact object.A compact object is the same as the original object, except with keys containing falsy values removed. This operation applies to the object and any nested objects. Arrays are considered objects where the indices are keys. A value is considered falsy when
Boolean(value)
returnsfalse
.You may assume the
obj
is the output ofJSON.parse
. In other words, it is valid JSON. - LeetCode
Solutions
If the input is an array, initializes a new array (compactArr
) and iterates over each item. If an item is truthy, recursively compacts the item and adds it to compactArr
.
If the input is an object, initializes a new object (compactObj
) and iterates over each key-value pair. If the value is truthy, recursively compacts the value and assigns it to the corresponding key in compactObj
.
Code
TypeScript
type JSONValue = null | boolean | number | string | JSONValue[] | { [key: string]: JSONValue };
type Obj = { [key: string]: JSONValue } | Array<JSONValue>;
const compactObject = function(obj: Obj): Obj {
if (typeof obj !== 'object' || obj == null) {
return obj;
}
if (Array.isArray(obj)) {
const compactArr: JSONValue[] = [];
obj.forEach((item) => {
if (item) {
compactArr.push(compactObject(item as Obj));
}
});
return compactArr;
}
const compactObj: { [key: string]: JSONValue } = {};
Object.entries(obj).forEach(([key, value]) => {
if (value) {
compactObj[key] = compactObject(value as Obj);
}
});
return compactObj;
};
Sort By
Given an array
arr
and a functionfn
, return a sorted arraysortedArr
. You can assumefn
only returns numbers and those numbers determine the sort order ofsortedArr
.sortedArray
must be sorted in ascending order byfn
output.You may assume that
fn
will never duplicate numbers for a given array. - LeetCode
Solutions
Simply use .sort()
method.
Code
TypeScript
type JSONValue = null | boolean | number | string | JSONValue[] | { [key: string]: JSONValue };
type Fn = (value: JSONValue) => number
const sortBy = function(arr: JSONValue[], fn: Fn): JSONValue[] {
return arr.sort((a, b) => fn(a) - fn(b));
};
Array.of()
The
Array.of()
static method creates a newArray
instance from a variable number of arguments, regardless of number or type of the arguments. - MDN
Solutions
The arguments
object is an array-like object accessible within functions that contains the values of the arguments passed to that function.
The slice
method is used to create a shallow copy of a portion of an array into a new array object.
By calling slice
on the arguments
object with the call
method, we convert the arguments
object into a true array.
Code
TypeScript
const ArrayOf = function (){
return [].slice.call(arguments);
}
Array to Tree
Convert an array to tree-like structure.
Solutions
Iterates over each item in flatArray
. For each item, checks if the parentId
of the item matches the parentId
parameter.
If the item's parentId
matches, recursively calls arrayToTree
with the current item’s id
as the new parentId
to find its children. The result of this recursive call is stored in the children
array.
A new node object is created with id
, name
, and children
properties. This node is then added to the tree
array.
Code
TypeScript
interface FlatNode {
id: number;
name: string;
parentId: number | null;
}
interface TreeNode {
id: number;
name: string;
children: TreeNode[];
}
const arrayToTree = function(flatArray: FlatNode[], parentId: number | null = null): TreeNode[] {
const tree: TreeNode[] = [];
flatArray.forEach(item => {
if (item.parentId === parentId) {
const children = arrayToTree(flatArray, item.id);
const node: TreeNode = {
id: item.id,
name: item.name,
children: children
};
tree.push(node);
}
});
return tree;
};
Intersection
Given 2 sorted array of integers, find the elements that exist in both arrays.
Solutions
Initializes a set with the elements of the first array. Iterates over the remaining arrays one by one. For each subsequent array, checks if each element in the set is present in the current array. If an element is not found in the current array, removed from the set.
Code
TypeScript
export default function intersection<T>(...arrays: T[][]): T[] {
if (arrays.length === 0) {
return [];
}
const set = new Set(arrays[0]);
for (let i = 1; i < arrays.length; i++) {
set.forEach((value) => {
if (!arrays[i].includes(value)) {
set.delete(value);
}
});
}
return Array.from(set);
}
Shuffle
How would you implement a shuffle() ?
When passed with an array, it should modify the array inline to generate a randomly picked permutation at the same probability.
Solutions
Fisher-Yates algorithm.
Code
TypeScript
const shuffle = function<T>(arr: T[]): T[] {
for (let i = 0; i < arr.length; i++) {
const randIdx = Math.floor(Math.random() * (i + 1));
[arr[randIdx], arr[i]] = [arr[i], arr[randIdx]];
}
return arr;
};