42Entwickler 1.0.1.1

dotnet add package 42Entwickler --version 1.0.1.1
                    
NuGet\Install-Package 42Entwickler -Version 1.0.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="42Entwickler" Version="1.0.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="42Entwickler" Version="1.0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="42Entwickler" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add 42Entwickler --version 1.0.1.1
                    
#r "nuget: 42Entwickler, 1.0.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package 42Entwickler@1.0.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=42Entwickler&version=1.0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=42Entwickler&version=1.0.1.1
                    
Install as a Cake Tool

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> or IComparable<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, and IEnumerable<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 through
  • tag (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 when htmlCode, tag, or attribute is 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

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!

Donate with PayPal

If you want to become a professional supporter and need an invoice - no problem.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1.1 208 6/19/2025
1.0.1 196 6/19/2025