Filtering with URN logic
The CitableBase package identifies three kinds of URN comparison: equality, containment and similarity. We want to be able to apply that logic to query our new ReadingList type. If your citable collection includes objects cited by Cite2Urn or CtsUrn, this is as simple as filtering the collection using their urnequals, urncontains or urnsimilar functions. Since we have defined a custom Isbn10Urn type, we'll need to implement those functions for our new URN type. We'll digress briefly with that implementation before turning to filtering our citable collection.
For an introduction to defining URN types and implementing the UrnComparable trait, see the documentation for the CitableBase package
Digression: implementing URN comparison on Isbn10Urn
The CitableBase package provides a concrete implementation of urnequals, but we need to import and define functions for urncontains and urnsimilar
Containment
For our ISBN type, we'll define "containment" as true when two ISBNS belong to the same initial-digit group (0 - 4). We'll use the components functions from CitableBase to extract the third part of the URN string, and compare its first character.
import CitableBase: urncontains
function urncontains(u1::Isbn10Urn, u2::Isbn10Urn)
initial1 = components(u1.isbn)[3][1]
initial2 = components(u2.isbn)[3][1]
initial1 == initial2
endurncontains (generic function with 3 methods)Both Distant Horizons and Enumerations are in ISBN group 0.
urncontains(distanthorizons, enumerations)trueBut Can We Be Wrong? is in ISBN group 1.
urncontains(distanthorizons, wrong)falseSimilarity
We'll define "similarity" as belonging to the same language area. In this definition, both 0 and 1 indicate English-language countries.
# True if ISBN starts with `0` or `1`
function english(urn::Isbn10Urn)
langarea = components(urn.isbn)[3][1]
langarea == '0' || langarea == '1'
end
import CitableBase: urnsimilar
function urnsimilar(u1::Isbn10Urn, u2::Isbn10Urn)
initial1 = components(u1.isbn)[3][1]
initial2 = components(u2.isbn)[3][1]
(english(u1) && english(u2)) || initial1 == initial2
endurnsimilar (generic function with 2 methods)Both Distant Horizons and Can We Be Wrong? are published in English-language areas.
urnsimilar(distanthorizons, wrong)trueFiltering a citable collection
Whether you use Cite2Urns, CtsUrns, or define your own URN type, as we did for ISBNs, filtering a collection of your content with URN logic is straightforward. All you need to do is define functions for urnequals, urncontains and urnsimilar that take a URN parameter to filter with (here, an Isbn10Urn), and a citable collection to filter (here, a ReadingList). If no objects match, we'll return nothing; otherwise, we'll return a list of content matching your URN.
function urnequals(isbn::Isbn10Urn, rlist::ReadingList)
matches = filter(i -> i == isbn, rlist.reff)
isempty(matches) ? nothing : matches
end
function urncontains(isbn::Isbn10Urn, rlist::ReadingList)
matches = filter(i -> urncontains(i, isbn), rlist.reff)
isempty(matches) ? nothing : matches
end
function urnsimilar(isbn::Isbn10Urn, rlist::ReadingList)
matches = filter(i -> urnsimilar(i, isbn), rlist.reff)
isempty(matches) ? nothing : matches
endurnsimilar (generic function with 3 methods)urnequals(jane, rl)1-element Vector{Main.Isbn10Urn}:
Main.Isbn10Urn("urn:isbn:0141395203")group1 = Isbn10Urn("urn:isbn:1")
urncontains(group1, rl)1-element Vector{Main.Isbn10Urn}:
Main.Isbn10Urn("urn:isbn:1108922036")urnsimilar(group1, rl)5-element Vector{Main.Isbn10Urn}:
Main.Isbn10Urn("urn:isbn:022661283X")
Main.Isbn10Urn("urn:isbn:022656875X")
Main.Isbn10Urn("urn:isbn:022656875X")
Main.Isbn10Urn("urn:isbn:1108922036")
Main.Isbn10Urn("urn:isbn:0141395203")