42Entwickler 1.0.1.1
dotnet add package 42Entwickler --version 1.0.1.1
NuGet\Install-Package 42Entwickler -Version 1.0.1.1
<PackageReference Include="42Entwickler" Version="1.0.1.1" />
<PackageVersion Include="42Entwickler" Version="1.0.1.1" />
<PackageReference Include="42Entwickler" />
paket add 42Entwickler --version 1.0.1.1
#r "nuget: 42Entwickler, 1.0.1.1"
#:package 42Entwickler@1.0.1.1
#addin nuget:?package=42Entwickler&version=1.0.1.1
#tool nuget:?package=42Entwickler&version=1.0.1.1
42Entwickler
A lightweight and flexible .NET Standard library providing several functionality:
- GenericEqualityComparer<T> generic equality comparer that allows you to define custom comparison and hash functions for any type
- LINQ-
Shuffle-Method that allows to return a collection in shuffled order. - HtmlSearchIterator a fast and efficient way to search through HTML documents using
IEnumerable<string>and implementing the iterator pattern.
๐ฆ Installation
This library is available as a NuGet package:
dotnet add package 42Entwickler
Or add it to your .csproj:
<PackageReference Include="42Entwickler" />
This library is compatible with .NET Standard 2.0 and thus works with most .NET projects (e.g., .NET Framework, .NET Core, .NET 5/6/7/...).
GenericEqualityComparer
โจ Features
- Use a custom equality function and hash function for any type.
- Automatically supports types that implement
IComparable<T>. - Works with collections such as
Dictionary,HashSet, and LINQ.Distinct(). - Supports both generic and non-generic
IEqualityComparer.
๐ก Use Case
Ideal when:
- You want to use structural equality for types without modifying their code.
- You need to compare objects based on specific properties.
- You work with types that don't implement
IEquatable<T>orIComparable<T>.
1. Using IComparable<T> (e.g. int, DateTime, etc.)
using System;
using System.Collections.Generic;
using _42Entwickler;
var comparer = new GenericEqualityComparer<int>(x => x.GetHashCode());
var set = new HashSet<int>(comparer);
set.Add(5);
set.Add(5); // Will not be added again
Console.WriteLine(set.Count); // 1
๐งช Notes
If your type does not implement IComparable<T>, you must provide a custom equality function.
2. Custom equality and hash function (e.g. comparing by a property)
using System;
using System.Collections.Generic;
using _42Entwickler;
record Person(string FirstName, string LastName);
var comparer = new GenericEqualityComparer<Person>(
getHashCode: p => p.LastName.GetHashCode(),
equals: (p1, p2) => p1.LastName == p2.LastName
);
var list = new List<Person>
{
new("Alice", "Smith"),
new("Bob", "Smith"),
new("Carol", "Johnson")
};
var distinct = new HashSet<Person>(list, comparer);
foreach (var person in distinct)
{
Console.WriteLine(person); // Only one Smith will remain
}
LINQ Shuffle
โจ Features
Allows to shuffle with a given random object or random seed for predictive shuffling or just without anything for "real" shuffling of a collection.
๐ก Using
using _42Entwickler.LINQ;
string[] data = { "A", "B", "C", "D", "E" };
IEnumerable<string> shuffled = data.Shuffle(); // Returns the data in a shuffled order.
Console.WriteLine(String.Join(', ', shuffled));
// Output: C, A, E, B, D (example output, actual order will vary)
HtmlSearchIterator
A high-performance HTML attribute value extractor with iterator support for .NET applications.
๐ Features
- High Performance: Optimized string searching with aggressive inlining
- Iterator Support: Compatible with
foreach, LINQ, andIEnumerable<string> - Case-Insensitive: Handles both tags and attributes case-insensitively
- Robust Parsing: Handles quoted/unquoted attributes, self-closing tags, and malformed HTML
- Memory Efficient: Lazy evaluation with iterator pattern
- Filter Support: Optional predicate filtering of results
๐ง Basic Usage
Simple Attribute Extraction
using _42Entwickler;
string html = @"
<html>
<body>
<a href='https://github.com'>GitHub</a>
<a href=""https://stackoverflow.com"">Stack Overflow</a>
<img src=""/images/logo.png"" alt=""Logo"" />
</body>
</html>";
// Extract all href attributes from <a> tags
var linkIterator = new HtmlSearchIterator(html, "a", "href");
foreach (string url in linkIterator)
{
Console.WriteLine($"Found link: {url}");
}
// Output:
// Found link: https://github.com
// Found link: https://stackoverflow.com
With LINQ
var iterator = new HtmlSearchIterator(html, "img", "src");
var imagePaths = iterator
.Where(src => src.EndsWith(".png"))
.Take(5)
.ToList();
Console.WriteLine($"Found {imagePaths.Count} PNG images");
๐ฏ Advanced Usage
Filtered Extraction
// Only extract HTTPS URLs
var httpsIterator = new HtmlSearchIterator(html, "a", "href",
url => url.StartsWith("https://"));
foreach (string secureUrl in httpsIterator)
{
Console.WriteLine($"Secure link: {secureUrl}");
}
Multiple Iterations
var iterator = new HtmlSearchIterator(html, "a", "href");
// First iteration
var allLinks = iterator.ToList();
// Second iteration (works independently)
var firstThreeLinks = iterator.Take(3).ToArray();
Real-World Example: Extract All Images
string webpageHtml = await httpClient.GetStringAsync("https://example.com");
var imageIterator = new HtmlSearchIterator(webpageHtml, "img", "src");
var images = imageIterator
.Where(src => !string.IsNullOrEmpty(src))
.Select(src => src.StartsWith("//") ? "https:" + src : src)
.Where(src => Uri.IsWellFormedUriString(src, UriKind.Absolute))
.Distinct()
.ToList();
Console.WriteLine($"Found {images.Count} unique images");
๐ API Reference
Constructor
public HtmlSearchIterator(string htmlCode, string tag, string attribute, Predicate<string>? execute = null)
Parameters:
htmlCode(string): The HTML content to search throughtag(string): The HTML tag name to search for (e.g., "a", "img", "div")attribute(string): The attribute name to extract values from (e.g., "href", "src", "class")execute(Predicate<string>?, optional): Filter predicate for attribute values
Exceptions:
ArgumentException: Thrown whenhtmlCode,tag, orattributeis null or empty
Supported HTML Features
โ
Quoted Attributes: href="value" and href='value'
โ
Unquoted Attributes: href=value
โ
Case-Insensitive Tags: <A>, <a>, <IMG> all work
โ
Case-Insensitive Attributes: HREF, href, Href all work
โ
Self-Closing Tags: <img src="..." />
โ
Malformed HTML: Graceful handling of unclosed quotes, missing >
โ
Whitespace Handling: Proper trimming and normalization
โก Performance Tips
Best Practices
// โ
Good: Reuse iterator for multiple operations
var iterator = new HtmlSearchIterator(html, "a", "href");
var count = iterator.Count();
var firstFive = iterator.Take(5).ToList();
// โ Avoid: Creating multiple iterators for same search
var count = new HtmlSearchIterator(html, "a", "href").Count();
var firstFive = new HtmlSearchIterator(html, "a", "href").Take(5).ToList();
Memory Efficiency
// โ
Memory efficient: Use iterator directly
foreach (var link in new HtmlSearchIterator(html, "a", "href"))
{
ProcessLink(link); // Process one at a time
}
// โ ๏ธ Memory intensive: Convert to collection first
var allLinks = new HtmlSearchIterator(html, "a", "href").ToList();
foreach (var link in allLinks)
{
ProcessLink(link);
}
๐งช Common Use Cases
Extract All Links
var links = new HtmlSearchIterator(html, "a", "href").ToList();
Extract All Images
var images = new HtmlSearchIterator(html, "img", "src").ToList();
Extract CSS Classes
var classes = new HtmlSearchIterator(html, "div", "class").ToList();
Extract Form Actions
var actions = new HtmlSearchIterator(html, "form", "action").ToList();
Extract JavaScript Sources
var scripts = new HtmlSearchIterator(html, "script", "src").ToList();
โ ๏ธ Limitations
- Not a full HTML parser: Designed for attribute extraction, not DOM manipulation
- No XPath/CSS selectors: Use simple tag + attribute combinations
- No nested tag support: Searches for direct tag-attribute pairs only
๐ License & Support Licensed under the MIT License.
๐ Author: 42Entwickler โ follow for more .NET tips and tooling!
If you want to become a professional supporter and need an invoice - no problem.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Memory (>= 4.6.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.