using System.Text; namespace TarninaHub.Application.Text; public static class KeywordExtractor { private static readonly HashSet StopWords = new(StringComparer.OrdinalIgnoreCase) { "i", "w", "we", "na", "z", "do", "nie", "że", "się", "jest", "to", "dla", "od", "po", "o", "a", "ale", "jak", "co", "oraz", "przez", "przy", "tak", "już", "czy", "ich", "the", "and", "for", "with", "this", "that", "are", "was", }; public static IReadOnlyList Extract(string text, int max = 8) { if (string.IsNullOrWhiteSpace(text) || max <= 0) { return []; } var counts = new Dictionary(StringComparer.OrdinalIgnoreCase); var order = new List(); foreach (var rawToken in Tokenize(text)) { var token = rawToken.ToLowerInvariant(); if (token.Length < 3 || StopWords.Contains(token)) { continue; } if (!counts.TryGetValue(token, out var count)) { order.Add(token); } counts[token] = count + 1; } return order .OrderByDescending(token => counts[token]) .ThenBy(token => order.IndexOf(token)) .Take(max) .ToList(); } private static IEnumerable Tokenize(string text) { var buffer = new StringBuilder(); foreach (var character in text) { if (char.IsLetter(character)) { buffer.Append(character); } else if (buffer.Length > 0) { yield return buffer.ToString(); buffer.Clear(); } } if (buffer.Length > 0) { yield return buffer.ToString(); } } }