1console.log("hello-world);
console.log("hello-world);
.container {
width: 80%;
}
<pre><code class="language-css">
.container {
width: 80%;
}
</code></pre>
1console.log("hello-world);
console.log("hello-world);
.container {
width: 80%;
}
<pre><code class="language-css">
.container {
width: 80%;
}
</code></pre>
Understanding DOM Manipulation using JavaScript is a crucial skilI. In this comprehensive guide, we will explore various ways to remove ‘li’ elements from a ‘ul’ list in JavaScript. This guide will walk you through various methods, complete with HTML and JavaScript code samples, and common pitfalls to avoid and some very advanced tips (handling nested data structures, chunking large Sets and avoiding circular references).
Array.from()
method transforms a Set into an Array. Note that we need to convert Set to Array before JSON serialization, as direct JSON serialisation not possible for Set.
const mySet = new Set(['apple', 'banana', 'cherry']);
const setToJson = JSON.stringify(Array.from(mySet));
console.log(setToJson); // Outputs: '["apple", "banana", "cherry"]'
Spread syntax expands Set elements into an Array. So it is also a Array conversion of Set. After this we can do JSON serialization.
const mySet = new Set(['apple', 'banana', 'cherry']);
const setToJson = JSON.stringify([...mySet]);
console.log(setToJson); // Outputs: '["apple", "banana", "cherry"]'
Parse the JSON string and use the Set constructor for converting JSON to Set. Note that, we need to parse JSON before converting to a Set. We cannot directly convert from JSON string to Set.
const mySet = new Set(['apple', 'banana', 'cherry']);
const jsonToSet = new Set(JSON.parse(setToJson));
console.log(jsonToSet); // Outputs: Set {'apple', 'banana', 'cherry'}
We can use a replacer function in JSON.stringify()
for complex objects, like when Set exists as an Object Property. Appropriate implementation of the replacer function will be required. As discussed earlier, Array conversion of Set is done before we can JSON serialise the Set.
const objWithSet = { "fruits": new Set(["apple", "banana"]) };
function replacer(key, value) {
return value instanceof Set ? Array.from(value) : value;
}
const objToJson = JSON.stringify(objWithSet, replacer);
console.log(objToJson); // Outputs: '{"fruits":["apple","banana"]}'
Avoid Direct Serialization: Remember, Sets cannot be directly serialized to JSON. Usually need to be converted to Array first.
Use Correct Methods: Choose between Array.from()
and spread syntax based on context.
Handle Nested Objects Carefully: When dealing with objects containing Sets, a replacer function is essential.
Circular reference Error: Circular references occur when an object references itself directly or indirectly, forming a loop. This can cause issues in serialization as it leads to infinite loops. In following example, circularReference
is an object that references itself. Directly serializing it with JSON.stringify
throws a TypeError
. The solution is to use a custom replacer function that tracks objects that have already been seen (using a WeakSet
) and skips them to avoid circularity.
const circularReference = {};
circularReference.self = circularReference;
// A naive serialization attempt would result in a TypeError
try {
JSON.stringify(circularReference);
} catch (error) {
console.error(error.message); // Output: Converting circular structure to JSON
}
// Custom replacer function to handle circular references
function circularReplacer() {
const seen = new WeakSet();
return (key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) {
return;
}
seen.add(value);
}
return value;
};
}
const safeSerialized = JSON.stringify(circularReference, circularReplacer());
console.log(safeSerialized); // Output: '{"self":{}}'
Following function serializeLargeSet
takes a large Set and a chunk size.
It iterates over the Set in chunks, reducing the immediate memory footprint compared to converting the entire Set into an array at once.
Each chunk is serialized individually and concatenated into a final string.
This approach is more memory-efficient and can handle very large Sets without significant performance degradation.
// Example of handling large Sets efficiently
const largeSet = new Set(/* large dataset */);
function serializeLargeSet(set, chunkSize = 1000) {
let result = '[';
const iterator = set.values();
let done = false;
while (!done) {
const chunk = Array.from({ length: chunkSize }, () => {
const next = iterator.next();
done = next.done;
return next.value;
}).filter(v => v !== undefined);
if (chunk.length > 0) {
result += chunk.map(JSON.stringify).join(',');
}
}
result += ']';
return result;
}
const optimizedSerialization = serializeLargeSet(largeSet);
console.log(optimizedSerialization);
serializeComplexStructure
: This function takes any complex data structure as input. It uses a custom replacer
function for JSON.stringify
, which is where the core logic for handling different types of data resides.When encountering a Set, the function converts it to an array using Array.from
.
It then maps over the array elements, recursively calling the replacer function to handle nested Sets or Objects.
For Objects, the function uses Object.fromEntries
combined with Object.entries
to iterate over the object’s properties.
It applies the replacer function recursively to each value, allowing for nested Sets or Objects within Objects to be handled.
complexData
is a structured object that contains various nested Sets and Objects, demonstrating the function’s capability to handle multiple complex scenarios.
serializedData
holds the JSON string output of the serializeComplexStructure
function.
function serializeComplexStructure(data) {
function replacer(key, value) {
if (value instanceof Set) {
return Array.from(value).map(innerValue =>
innerValue instanceof Set || innerValue instanceof Object ? replacer(null, innerValue) : innerValue
);
} else if (value instanceof Object) {
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, replacer(k, v)]));
}
return value;
}
return JSON.stringify(data, replacer);
}
// Example Usage
const complexData = {
nestedSet: new Set([new Set(['a', 'b']), 'c']),
objectSet: new Set([{ key1: 'value1' }, { key2: 'value2' }]),
nestedObject: {
innerObject: {
key: 'value'
}
},
objectWithSet: {
setInside: new Set(['item1', 'item2'])
}
};
const serializedData = serializeComplexStructure(complexData);
console.log(serializedData);
// Outputs ⚠ (used line breaks for readability, might not be in real JSON):
// '{
// "nestedSet":[["a","b"],"c"],
// "objectSet":[{"key1":"value1"},{"key2":"value2"}],
// "nestedObject":{"innerObject":{"key":"value"}},
// "objectWithSet":{"setInside":["item1","item2"]}
// }'
In the spirit of Test Driven Development ( 😁), lets test our understanding by solving a problem.
Convert an object with nested Sets into JSON.
Problem (JavaScript)
const nestedObj = {
"numbers": new Set([1, 2]),
"moreNumbers": new Set([3, 4])
};
console.log(convertNestedSetsToJSON(nestedObj));
// Expected Output: '{"numbers":[1,2],"moreNumbers":[3,4]}'
Please attempt before seeing the Answer:
function convertNestedSetsToJSON(obj) {
function replacer(key, value) {
return value instanceof Set ? Array.from(value) : value;
}
return JSON.stringify(obj, replacer);
}
Explanation:
convertNestedSetsToJSON
function uses JSON.stringify
with a replacer to ensure Sets are converted to arrays, maintaining data integrity during serialization.With these techniques and tips, you can confidently handle Set to JSON conversions in JavaScript. Understanding such nuances of data structures is important to make us better javascript developers.
Keep coding! 🚀👨💻
Feel free to reach out!