mgtzm/src/util.zig

43 lines
1.5 KiB
Zig

const std = @import("std");
pub const IntersectionIterator = struct {
ref: std.mem.TokenIterator(u8),
rest: []const []const u8,
/// Returns the next occurrence or null. Returned value is owned by originally passed slice
pub fn next(self: *IntersectionIterator) ?[]const u8{
// If this returns null, there's no more items to check. We're finished.
const needle = self.ref.next() orelse return null;
// Search into every one of the strings
haystack: for (self.rest) |haystack| {
// The items are separated by spaces, iterate through those
var haystack_iter = std.mem.tokenize(u8, haystack, " ");
// If the word is found, it short circuits and tries the next haystack
while (haystack_iter.next()) |hay_blade| {
if (std.mem.eql(u8, hay_blade, needle)) continue :haystack;
}
// If this point is reached, the needle wasn't found.
// Try the next one
return self.next();
}
// If we got here, no not-matching haysack was found. A match!
return needle;
}
};
/// Finds the common tokens inside space separated strings
/// and returns a slice to the first token that matches
pub fn intersection(slices: []const []const u8) IntersectionIterator {
// Tokenize the first entry and save the rest as references to check
return IntersectionIterator{
.ref = std.mem.tokenize(u8, slices[0], " "),
.rest = slices[1..],
};
}