diff options
Diffstat (limited to 'js/where/where.test.html')
-rw-r--r-- | js/where/where.test.html | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/js/where/where.test.html b/js/where/where.test.html new file mode 100644 index 0000000..161ecf1 --- /dev/null +++ b/js/where/where.test.html @@ -0,0 +1,247 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <title>Where?</title> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <style> + body { + font-family: monospace; + padding: 20px; + max-width: 800px; + margin: 0 auto; + line-height: 1.6; + } + .console { + background: #f5f5f5; + padding: 20px; + border-radius: 4px; + margin-top: 20px; + } + .example { + background: #e9f5ff; + padding: 15px; + border-radius: 4px; + margin: 10px 0; + } + code { + background: #f0f0f0; + padding: 2px 4px; + border-radius: 3px; + } + pre { + background: #f8f8f8; + padding: 15px; + border-radius: 4px; + overflow-x: auto; + } + </style> +</head> +<body> + <h1>Where?</h1> + + <section> + <h2>Overview</h2> + <p> + This <code>where()</code> function aims to provide sql-like filtering for arrays of objects. + It allows you to filter collections using simple or complex criteria, including nested properties. + </p> + <p> + Could you usually use <code>Array.filter()</code> instead? Yes, almost always. But I think this is a bit prettier. + </p> + </section> + + <section> + <h2>Basic Usage</h2> + <div class="example"> + <pre> +const users = [ + { name: 'Tziporah', age: 30 }, + { name: 'Bruce', age: 25 }, + { name: 'Ruth', age: 30 } +]; + +// Find everyone who is 30 years old +const thirtyYearOlds = where(users, { age: 30 }); +// Result: [{ name: 'Tziporah', age: 30 }, { name: 'Ruth', age: 30 }]</pre> + </div> + </section> + + <section> + <h2>More Advanced Features</h2> + + <h3>1. Nested Object Properties</h3> + <div class="example"> + <pre> +const users = [ + { + name: 'Bruce', + preferences: { + theme: 'dark', + notifications: { email: true } + } + } +]; + +// Find people with the dark theme enabled +const darkThemeUsers = where(users, { + preferences: { theme: 'dark' } +});</pre> + </div> + + <h3>2. Dot Notation</h3> + <div class="example"> + <pre> +// Same query using dot notation +const darkThemeUsers = where(users, { + 'preferences.theme': 'dark' +});</pre> + </div> + + <h3>3. Multiple Criteria</h3> + <div class="example"> + <pre> +// Find folks who are 30 AND prefer dark theme +const result = where(users, { + age: 30, + 'preferences.theme': 'dark' +});</pre> + </div> + + <h3>4. Array Matching</h3> + <div class="example"> + <pre> +const users = [ + { + name: 'Jeremiah', + hobbies: ['reading', 'music'] + } +]; + +// Find people with exact hobby matches +const readers = where(users, { + hobbies: ['reading', 'music'] +});</pre> + </div> + </section> + + <section> + <h2>The Key Features</h2> + <ul> + <li>Deep object comparison</li> + <li>Handles null/undefined values</li> + <li>Supports nested object and dot notation</li> + <li>Exact array matching</li> + <li>Multiple criteria (AND logic)</li> + <li>Memoized for performance 🏃♂️</li> + </ul> + </section> + + <section> + <h2>Limitations & Edge Cases</h2> + + <h3>1. Partial Array Matches</h3> + <div class="example"> + <pre> +const users = [ + { + name: 'Bruce', + hobbies: ['reading', 'music', 'hiking'] + } +]; + +// This won't match Bruce's hobbies +const result = where(users, { + hobbies: ['reading', 'music'] +}); // Returns [] + +// Arrays must match exactly in length and content</pre> + </div> + + <h3>2. OR Operations</h3> + <div class="example"> + <pre> +// This won't work for finding users aged 25 OR 30 +const result = where(users, { + age: [25, 30] // This looks for an exact array match +}); + +// Consider using Array.filter() directly for OR operations: +const result = users.filter(user => + user.age === 25 || user.age === 30 +);</pre> + </div> + + <h3>3. Complex Comparisons</h3> + <div class="example"> + <pre> +// These operations are NOT supported: +where(users, { + age: (age) => age > 30, // Function predicates + salary: { $gt: 50000 }, // MongoDB-style operators 🤮 + 'name.length': 4 // Property operations +});</pre> + </div> + + <h3>4. Regular Expressions</h3> + <div class="example"> + <pre> +// RegExp matching also isn't implemented +where(users, { + email: /.*@gmail\.com$/ +}); + +// Use Array.filter() instead: +const gmailUsers = users.filter(user => + /.*@gmail\.com$/.test(user.email) +);</pre> + </div> + + <h3>5. When Not to Use</h3> + <ul> + <li><strong>Complex Filtering Logic:</strong> If you need OR conditions, ranges, or custom predicates</li> + <li><strong>Large Data Sets:</strong> When performance is critical and you need indexed operations...probably don't use JavaScript</li> + <li><strong>Dynamic Queries:</strong> When query conditions need to be built from different operators on the fly</li> + <li><strong>Partial Matches:</strong> When you need partial array matches or when a string contains operations</li> + </ul> + + <h3>6. Performance Considerations</h3> + <div class="example"> + <pre> +// Avoid deeply nesting with large arrays +const deeplyNested = where(largeArray, { + 'level1.level2.level3.level4.property': value +}); + +// Each level of nesting increases complexity + +// Use direct access whenever possible: +const result = largeArray.filter(item => + item.level1?.level2?.level3?.level4?.property === value +);</pre> + </div> + </section> + + <h2>Test Results</h2> + <div class="console" id="output"></div> + + <script> + // Capture console output + const output = document.getElementById('output'); + const originalLog = console.log; + const originalError = console.error; + + console.log = function(msg) { + output.innerHTML += msg + '<br>'; + originalLog.apply(console, arguments); + }; + + console.error = function(msg) { + output.innerHTML += `<span style="color: red">${msg}</span><br>`; + originalError.apply(console, arguments); + }; + </script> + <script src="where.js"></script> + <script src="where.test.js"></script> +</body> +</html> \ No newline at end of file |