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
end
urncontains (generic function with 3 methods)
Both Distant Horizons and Enumerations are in ISBN group 0.
urncontains(distanthorizons, enumerations)
true
But Can We Be Wrong? is in ISBN group 1.
urncontains(distanthorizons, wrong)
false
Similarity
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
end
urnsimilar (generic function with 2 methods)
Both Distant Horizons and Can We Be Wrong? are published in English-language areas.
urnsimilar(distanthorizons, wrong)
true
Filtering a citable collection
Whether you use Cite2Urn
s, CtsUrn
s, 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
end
urnsimilar (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")