This is a collection of short JavaScript programming solutions that you will encounter everyday.
As with any programming language, JavaScript has its own way of solving problems. Knowing how to do basic data type conversion or array manipulations will make you deliver your solutions faster π.
I hope this helps you to be a more efficient JavaScript developer π€ππ€.
Feel free to reach out to me π€!
Blog || Open Source Project || Band Camp
If you want to make a suggestion or contribute to this, feel free to pull the repo and make a pull request!
1. Create an array of number from an array of an object and do calculation
input
const input = [
{ name: "name A", score: 2 },
{ name: "name B", score: 1 },
{ name: "name C", score: 4 },
{ name: "name D", score: 5 },
];
output
# (1) Create an array
[2, 1, 4, 5]
# (2) Return Sum of the array
12
# (3) Return Max
5
Answer
Array.prototype.map will create an array of the value from the selected key in the JSON object.
Array.prototype.reduce will accumulate the number. The first argument is the accumulator function and second argument is the starting value.
Function.prototype.apply takes this value as a first argument and an array as a second argument. It will apply the function to the array. For example, Math.sum.apply(null, [1, 2, 3]) will sum up all the numbers in the array. Math.sum works with Math.sum(1, 2, 3). But, to make it work with an array, we need to use apply function.
# (1)
input.map(x => x.score);
// alternatively we can map array without .map()
// Array.from takes mapFunction as a second argument, which will be called on every element of an array.
Array.from(input, ({score}) => score);
# (2)
imput.map(x => x.score).reduce((a, b) => a + b, 0);
# (3)
Math.max.apply(null, input.map(x => x.score));
// or use spread operator
Math.max(...input.map(x => x.score));
2. Getting max datetime from a string from the object array
input
const input = [
{ datetime: "2020-04-29T03:23:48Z", spend: 300.0 },
{ datetime: "2020-06-03T23:26:43Z", spend: 300.0 },
{ datetime: "2020-05-30T17:28:14Z", spend: 300.0 },
{ datetime: "2020-06-27T18:21:07Z", spend: 300.0 },
];
output - return it as a Date object in the local time
Sun Jun 28 2020 04:21:07 GMT+1000
Answer
We can convert the string into a local time with new Date(). Then use the technique from question 1 to create an datetime array and apply max.
new Date(
Math.max.apply(
null,
input.map((x) => new Date(x.datetime))
)
);
// or use spread
new Date(Math.max(...input.map((x) => new Date(x.datetime))));
3. Adding new key-value pair in all the objects in an array
You have an array of an object with name. Can you add an unique id to all the objects?
input
const input = [{ name: "John" }, { name: "Tyson" }, { name: "Joan" }];
output
[
{ name: "John", id: 1 },
{ name: "Tyson", id: 2 },
{ name: "Joan", id: 3 },
];
Answer
We can use the map and use the index to add an unique id that increments.
input.map((data, index) => ({ name: data.name, id: index + 1 }));
4. Sorting object array by a key
input
const input = [
{ name: "John", score: "432" },
{ name: "Joe", score: "125" },
{ name: "Zoe", score: "320" },
{ name: "Ziggy", score: "532" },
{ name: "Dave", score: "211" },
{ name: "Sarah", score: "621" },
];
output - sort it in descending order
0: {name: "Sarah", score: "621"}
1: {name: "Ziggy", score: "532"}
2: {name: "John", score: "432"}
3: {name: "Zoe", score: "320"}
4: {name: "Dave", score: "211"}
5: {name: "Joe", score: "125"}
Answer
Array.prototype.sort takes a callback function as a sorter. We can write a simple call back function and pass it.const sorter = (key) => {
return (a, b) => {
if (a[key] > b[key]) {
return -1;
} else if (a[key] < b[key]) {
return 1;
} else {
return 0;
}
};
};
input.sort(sorter("score"));
The above solution is too convoluted if we just want to sort by score. We can do this. This however does not work with name
because they are string values.
// Ascending
input.sort((a, b) => a.score - b.score);
// Descending
input.sort((a, b) => b.score - a.score);
// This doesn't work...
input.sort((a, b) => b.name - a.name);
5. Sorting object array by multiple keys
We sorted an object array by a key in the previous question. What if the score is tie and want to sort it by the second key, name.
input
const input = [
{ name: "John", score: "432" },
{ name: "Joe", score: "125" },
{ name: "Zoe", score: "320" },
{ name: "Ziggy", score: "532" },
{ name: "Dave", score: "211" },
{ name: "Sarah", score: "621" },
{ name: "Alex", score: "320" },
];
output - see when the sore is the same, it's sorted by name.
0: {name: "Sarah", score: "621"}
1: {name: "Ziggy", score: "532"}
2: {name: "John", score: "432"}
3: {name: "Alex", score: "320"}
4: {name: "Zoe", score: "320"}
5: {name: "Dave", score: "211"}
6: {name: "Joe", score: "125"}
Answer
Apply the same method for the previous question. When the first key is the same, we can add another logic to sort it by the second key. Reference here
function rankingSorter(firstKey, secondKey) {
return function (a, b) {
if (a[firstKey] > b[firstKey]) {
return -1;
} else if (a[firstKey] < b[firstKey]) {
return 1;
} else {
if (a[secondKey] > b[secondKey]) {
return 1;
} else if (a[secondKey] < b[secondKey]) {
return -1;
} else {
return 0;
}
}
};
}
input.sort(rankingSorter("score", "name"));
6. Sorting object array by datetime
Sort array by datetime.
input
const arrays = [
{ datetime: "2020-04-29T03:23:48Z", spend: 300.0 },
{ datetime: "2020-06-03T23:26:43Z", spend: 300.0 },
{ datetime: "2021-05-30T17:28:14Z", spend: 300.0 },
{ datetime: "2020-06-27T18:21:07Z", spend: 300.0 },
];
output - return the latest datetime record
{datetime: '2021-05-30T17:28:14Z', spend: 300.00}
Answer
Use custom function for sort. getTime() will convert datetime to a number of milliseconds since midnight Jan 1, 1970. We can also use localeCompare()
method which returns a number indicating whether a reference string comes before, or after, or is the same as the given string in sort order.
arrays.sort((a, b)
=> new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
)[0]
// Using localeCompare()
arrays.sort(
function(a,b){
return b.datetime.localeCompare(a.datetime)
})
7. Update object values
// input
const height = {
john: 170,
allen: 182,
jack: 168,
};
// output
const output = {
john: "170cm",
allen: "182cm",
jack: "168cm",
};
Answer
Use Object.entries
to create an array of the key-value pairs.
Object.entries(height)
will create [['john', 170], ...]
. Then, we can destructure the nested arrays with [k, v]
in the map
method.
const output = Object.entries(height).map(([k, v]) => ({ [k]: `${v}cm` }));
8. Aggregate by year
Aggregate the percentage by key.
input
const breakdown = [
{
percentage: 80,
key: 2011,
},
{
percentage: 10,
key: 2010,
},
{
percentage: 5,
key: 2011,
},
{
percentage: 5,
key: 2010,
},
{
percentage: 5,
key: 2011,
},
];
output - return the sum of percentage by year.
[
{
percentage: 90,
key: 2011,
},
{
percentage: 15,
key: 2010,
},
];
Answer
Approach 1: We can sort the data in a descending order and then use reduce to aggregate.
const sorted = breakdown.sort((a, b) => a.key - b.key);
const aggregated = breakdown
.sort((a, b) => b.key - a.key)
.reduce((acc, next) => {
const currentAccIndex = acc.length - 1;
if (acc.length && acc[currentAccIndex].key === next.key) {
acc[currentAccIndex].percentage + next.percentage;
} else {
acc[currentAccIndex + 1] = next;
}
return acc;
}, []);
Approach 2: This feels more like a JS witchcraft, doesn't it? Using Object.entries
, and then reduce to aggregate.
const result = Object.entries(
breakdown.reduce(
(aggregate, current) => ({
...aggregate,
[current.key]:
(aggregate[current.key] ? aggregate[current.key] : 0) +
current.percentage,
}),
{}
)
).map((aggregate) => ({
year: aggregate[0],
percentage: aggregate[1],
}));
console.log(`output from the 3rd way ${JSON.stringify(result)}`);
1. Create an array with a sequence of number
output
[0, 1, 2, 3, 4];
Answer
We can use either spread operator or Array from() and key() for ES6β
For a reference, knowing how to use the Set object is great. Interestingly, this is not supported by IE11. If you do Array.from(new Set([1, 2, 3])), you will get an empty array without an error. Use set polyfill for IE11 support.
[...Array(5).keys()];
Array.from(Array(5).keys());
Array.from(new Set([0, 1, 2, 3, 4]));
2. Removing duplicates from an array
Remove duplicate value from an array.
const arr = ["apple", "orange", "banana", "orange", "apple"];
Answer
The Set
type is new in ES6. It's similar to array, but not quite. It contains no duplicate value (member values are unique). So first, we dedupe by converting array into a set object and then convert back to an array with Array.from
or spread operator.
Array.from(new Set(arr));
// or
[...new Set(arr)];
3. Replace the specific value
Replace watermelon with blueberry in the array below.
input
const fruits = ["apple", "banana", "watermelon", "melon"];
output
["apple", "banana", "blueberry", "melon"];
Answer
Use map with if condition.
const newFruits = fruits.map((x) => {
if (x === "watermelon") return "blueberry";
return x;
});
4. modulo operation
Create an array of the reminder after dividing each by 3. Let's try map the value without using map(). What can you do?
input
const input = [3, 4, 5, 6, 7];
output
[0, 1, 2, 0, 1];
Answer
We can map array without using .map(). Array.from takes arrayLike object as an first argument and map function applied to every element of the array as a second argument. Third argument is the value to use as this when executing map function. Second and third arguments are optional.
Array.from(input, (x) => x % 3);
5. Empty an array
Empty the array below:
input
const arr = [1, 2, 3, 4];
output
[];
Answer
We can just set the array length to 0. That's it π€―
arr.length = 0;
6. Fill an empty array
Create an array of 10 1s as below.
output
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
Answer
We can use fill()
to fill an empty array with the value.
new Array(10).fill(1);
7. Find common value from two arrays
Find the common value from two arrays.
input
const numOne = [0, 2, 4, 6, 8, 8];
const numTwo = [1, 2, 3, 4, 5, 6];
output
[2, 4, 6];
Answer
First, we need de-duplicate the first array and use filter to find the common value.
[...new Set(numOne)].filter((x) => numTwo.includes(x));
8. Get random value from an array
Return random value from the color array below
const colors = ["blue", "white", "green", "navy", "pink", "black", "brown"];
Answer
Math.random()
gives a random number between 0 and one. Then, we multiply with length of the array and take the floor to generate random index.
colors[Math.floor(Math.random() * colors.length)];
9. Get the last index of the value that occurs
Get the last index of 5 occurs in the array below. You need to return 9.
const numbers = [1, 5, 2, 6, 3, 5, 2, 3, 6, 5, 2, 7];
Answer
Here is the interesting method that javascript has. lastIndexOf().
numbers.lastIndexOf(5);
9. Get the last element of an array
Get the last element of the array
const array = [1, 2, 3, 4];
output
4
Answer
array.slice(-1)[0];
array.slice(-1).pop;
array[array.length - 1];
10. Convert array to string
const language = ["Japanese", "Spanish", "English", "German"];
From the array above, return string representing the elements of the list.
output
# (1)
Japanese, Spanish, English, and German
# (2)
Japanese, Spanish, English, or German
# (3)
Japanese Spanish English German
Answer
Intl internationalization API has ListFormat
object. Intl.ListFormat
is supported in all major browsers except IE11.
// (1)
const listFormatter = new Intl.ListFormat("en", {
style: "long",
type: "conjunction",
});
console.log(listFormatter.format(language));
typeof listFormatter.format(language); // -> string
// (2)
const listFormatter = new Intl.ListFormat("en", {
style: "short",
type: "disjunction",
});
// (3)
const listFormatter = new Intl.ListFormat("en", {
style: "narrow",
type: "unit",
});
1. Currency Format
input
const amount = 2398622.26;
output
"$2,398,622.26";
Answer
By using toLocaleString(), we can format currency with one line π€―.
amount.toLocaleString("en-US", {
style: "currency",
currency: "USD",
});
We can natively format JavaScript Numbers.
If you want to do this without native API, it gets really intense...
const formatAmount = (amount) => {
const splitAmount = amount.split(".");
const dollar = splitAmount[0];
const decimal = splitAmount[1];
const index = dollar.length / 3;
const dollarArray = [];
for (let i = 1; i <= index + 1; i++) {
const startIndex = dollar.length - i * 2 - 1 - (i - 1);
const finalStartIndex = startIndex < 0 ? 0 : startIndex;
dollarArray.push(dollar.substring(finalStartIndex, startIndex + 3));
}
return `$${dollarArray.reverse().join(",")}.${decimal}`;
};
2. Datetime formatting
Formatting the datetime string below into a local time.
input
"2020-06-28T23:59:01Z";
output - this is the local time (AEST for me)
"29/06/2020 09:59:01 AM";
Answer
Let's give it a go by using Intl.DateTimeFormat. This will give you '29/06/2020'.
new Intl.DateTimeFormat("en-AU").format(new Date("2020-06-28T23:59:01Z"));
Now, Intl.DateTimeFormat has options. Let's pass the options.
const options = {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric",
hour12: true,
timeZone: "Australia/Sydney",
};
const formatted = new Intl.DateTimeFormat("en-AU", options).format(
new Date("2020-06-28T23:59:01Z")
);
The above will give us the output of '29/06/2020, 9:59:01 am'. We need to format this.
formatted.toUpperCase().split(", ").join(" ");
That's it π€!
If you want to do this without native API, it gets long π’.
formatUtcToLocal(timestamp: string): string {
const localTime = new Date(timestamp)
const year = localTime.getFullYear()
const month = this.formatSingleDigit(localTime.getMonth() + 1)
const day = this.formatSingleDigit(localTime.getDate())
const hour = this.formatSingleDigit(this.convertHour(localTime.getHours()))
const minutes = this.formatSingleDigit(localTime.getMinutes())
const seconds = this.formatSingleDigit(localTime.getSeconds())
const amOrPm = localTime.getHours() > 12 ? 'PM' : 'AM'
return `${day}/${month}/${year} ${hour}:${minutes}:${seconds} ${amOrPm}`
}
formatSingleDigit(value: number): string {
const formattedMonth = `0${value}`
return formattedMonth.substring(formattedMonth.length - 2, formattedMonth.length)
}
convertHour(hour: number): number {
if (hour > 12) {
return hour - 12
}
return hour
}
Spread syntax is cool π₯³. Use spread syntax for all the questions. Let's build spread syntax muscle memory π£π£π£!
1. Spread with arrays
input
const fruits = ["apple", "banana", "blueberry"];
const vegs = ["lettuce", "tomato"];
Without spread, we would use .concat()
to combine two arrays. Use spread syntax to .concat()
two arrays.
output
["apple", "banana", "blueberry", "lettuce", "tomato"];
Answer
const combined = [...fruits, ...vegis];
// it is the same as
const combined = fruits.concat(vegis);
2. Add object to an array
Create a new object with a new fruit added and preserve original fruits array the same.
input
const fruits = [
{ id: 1, item: "apple" },
{ id: 2, item: "orange" },
];
const newFruit = { id: 3, item: "banana" };
output
// Create a new object called newFruits
[
{ id: 1, item: "apple" },
{ id: 2, item: "orange" },
{ id: 3, item: "banana" },
];
Answer
const newFruits = [...fruits, newFruit];
If you use Array.push() as below, it will modify the original array fruits. With spreading, we can preserve the original array.
fruits.push(newFruit);
3. Create an array from a set
We can use spread syntax to create an iterable array from a set.
input
const fruitSet = new Set();
set.add("apple");
set.add("orange");
set.add("banana");
output - create a new array called fruitArray
["apple", "orange", "banana"];
Answer
Using spread syntax with a set object will create an array.
[...fruitSet];
Set is a collection of unique values (either primitive or object).
const fruitSet = new Set();
set.add("apple");
set.add("apple");
set.add("banana");
// Set only contains "apple" and "banana"
We can actually create an array with unique values with Set and spread syntax.
[...new Set(["apple", "banana", "apple", "banana", "orange"])];
// results in ['apple', 'banana', 'orange']
4. Create an array from a string
We can also use spread to create an array from a string.
input
const str = "spread";
output
["s", "p", "e", "a", "d"];
Answer
const strArray = [...str];
5. Copying an object
We can spread an object to copy and update. It is the equivalent of Object.assign().
input
const original = { id: 1, fruit: "apple" };
output - create an copy of the original, copied.
Answer
const copied = { ...original };
This is the equivalent of
const copied = Object.assign({}, original);
6. Adding a new property on an existing object
Add a new property to an existing object in an immutable fashion.
input
const fruit = { id: 1, name: "apple" };
output
{ id: 1, name: 'apple', sweet: true }
Answer
const updatedFruit = { ...fruit, sweet: true };
We can do the spread if the added property is an object as below.
const add = { sweet: true }
const updatedFruit = { ...fruit, ...add }
// Then this will create the object with a new property
{ id: 1, name: 'apple', sweet: true }
7. Updating a property on an existing object
Update an existing property to create a new object in an immutable fashion.
input
const fruit = { id: 1, name: "apple", taste: "good" };
Update two properties with spread syntax. output
{ id: 1, name: 'banana', taste: 'great' }
Answer
To update multiple properties, we can just add them as below.
const updatedFruit = { ...fruit, name: "banana", taste: "great" };
Note that the order of the properties does not matter.
We can do it like { ...fruit, taste: 'sweet', id: 4 }
and it updates the correct property as long as the name matches.
We can update the property of the object from an object with spread, too!
const update = { name: 'banana', taste: 'great' }
const updatedFruit = { ...fruit, ...update }
// this will update the property
{ id: 1, name: 'banana', taste: 'great' }
8. Spread with nested object
Spread with nested object gets hairy. See if you can add a new property to the nested object as below.
input
const fruit = {
id: 1,
item: {
name: "apple",
sweet: true,
},
};
output - add an price property to item
{
id: 1,
item: {
name: 'apple',
sweet: true,
price: 1.0
}
}
Answer
Nested objects need to be spread. In another word, we can spread the inner object, item, to retain the existing property.
const newFruit = { ...fruit, item: { ...fruit.item, price: 1.0 } };
9. More spread with nested objects
Use spread to update item.price.amount to 2.0.
input
const fruit = {
id: 1,
item: {
name: "apple",
sweet: true,
price: {
currency: "US",
amount: 1.0,
},
},
};
output - add an price property to item
{
id: 1,
item: {
name: 'apple',
sweet: true,
price: {
currency: 'US',
amount: 2.0
}
}
}
Answer
const updated = {
...fruit,
item: {
...fruit.item,
price: {
...fruit.item.price,
amount: 2.0,
},
},
};
10. Spread function call
Spread can be used in a function call. We have a function called addAll. This will take 3 parameters. If we have an array of 3 numbers, how can we use the function?
const addAll = (a, b, c) => a + b + c;
// use addAll function on the array below
const input = [1, 2, 3];
Answer
This is a cool use case. We can in fact pass the spread input.
addAll(...input);
This is the same as using apply(). But, spread makes it shorter.
addAll.apply(null, input);
11. Convert array to an object
Another interesting use case for spread. Convert the array to an object as below.
input
const arr = ["1", "2", "3"];
output
{ 0: '1', 1: '2', 2: '3' }
Answer
It's the quick and dirty way to convert an array to an object with spreadβ
{ ...arr }
In JavaScript, three dot syntax is interesting. It can be either spread or rest parameter syntax and they do exactly the opposite π€―. Let's test your knowledge on rest parameter syntax π.
1. ...args
What is the output of below?
function check(...args) {
console.log(args);
}
check(1, 2, 3, 4);
Answer
Rest parameter syntax will create an array instead of unpacking an array of object into individual values as in spread syntax.
The output will become an array of numbers π€―.
[1, 2, 3, 4];
2. ...args with other arguments
What is the output of below?
function check(firstNum, secondNum, ...args) {
console.log(firstNum);
console.log(secondNum);
console.log(args);
}
check(1, 2, 3, 4, 5);
Answer
Rest parameter syntax will create an array instead of unpacking an array of object into individual values as in spread syntax.
The output will become an array of numbers π€―.
1;
(2)[(3, 4, 5)];
3. Destructing an array
What is the output of below code?
const [first, ...rest] = ["apple", "banana", "grape"];
console.log(first);
console.log(rest);
Answer
Rest parameter can be used when destructing arrays. ...rest
will creates the shorter array.
apple[("banana", "grape")];
4. Destructing an object What is the output of below code?
const { id, ...rest } = { id: 1, name: "apple", price: 1.0 };
console.log(id);
console.log(rest);
Answer
Rest parameter can be used when destructing objects.
1
{ name: 'apple', price: 1.0 }
1. Truthy or Falsy?
Which one is evaluated as truthy?
- the number
0
- the BigInt
0n
- the keyword
null
- the keyword
undefined
- the boolean
false
- the number
NaN
- empty string
''
- empty array
[]
- empty object
{}
Answer
Empty array []
and empty object {}
are evaluated as truthy
.
Any primitive type evaluate to true in JavaScript, with the exception of 1 to 7 π€―.
2. What is !!
?
Answer
Returns an associated boolean value. True or false according to whether it is truthy or falsy values.
const number = 12;
!!number; // returns true
There is a great JavaScript questions to get to know the language better. Your JavaScript knowledge will skyrocket π. Check out javascript-questions
I subscribe to JavaScript Weekly. It's a weekly email informing you on what is happening on JS landscape as well as useful JS tips! Highly recommended.
There are many code challenges websites. My recommendation is edatbit.com. If you are comfortable with JavaScript, go to the expert level. These interesting bite-size challenges will be a holiday for your mind π΄.
You can get to build framework and library free JS apps from JavaScript30.com. It's free.
I am copy and pasting emoji from this website π₯°.