UNPKG

@natlibfi/marc-record

Version:

MARC record implementation in JavaScript

98 lines (97 loc) 2.87 kB
import createDebugLogger from "debug"; const debug = createDebugLogger("@natlibfi/marc-record:marcFieldSort"); const debugDev = debug.extend("dev"); export const defaultSorterFunctions = [sortByTag, sortAlphabetically]; export function fieldOrderComparator(fieldA, fieldB, sorterFunctions = defaultSorterFunctions) { function fieldToString(f) { if ("subfields" in f) { return `${f.tag} ${f.ind1}${f.ind2} \u2021${formatSubfields(f)}`; } return `${f.tag} ${f.value}`; function formatSubfields(field) { return field.subfields.map((sf) => `${sf.code}${sf.value || ""}`).join("\u2021"); } } for (const sortFn of sorterFunctions) { const result = sortFn(fieldA, fieldB); debugDev(`${sortFn.name}: '${fieldToString(fieldA)}' vs '${fieldToString(fieldB)}' ${result}`); if (result !== 0) { return result; } } return 0; } export function sortByTag(fieldA, fieldB) { function getSortIndex(tag) { const sortIndex = { LDR: "000", STA: "001.1", // STA comes now after 001. However 003+001 form a combo, so I'm not sure... SID: "999.1", LOW: "999.2", CAT: "999.3", HLI: "999.4" }; if (tag in sortIndex) { return sortIndex[tag]; } if (isNaN(tag)) { return "999.9"; } return tag; } const orderA = getSortIndex(fieldA.tag); const orderB = getSortIndex(fieldB.tag); if (orderA > orderB) { return 1; } if (orderA < orderB) { return -1; } return 0; } export function sortAlphabetically(fieldA, fieldB) { const tagToSortingSubfields = { "LOW": ["a"], "SID": ["b"] }; function scoreSubfieldsAlphabetically(setOfSubfields) { if (setOfSubfields.length === 0) { return 0; } const [subfieldCode, ...remainingSubfieldCodes] = setOfSubfields; const valA = selectFirstValue(fieldA, subfieldCode); const valB = selectFirstValue(fieldB, subfieldCode); if (!valA) { if (!valB) { return scoreSubfieldsAlphabetically(remainingSubfieldCodes); } return -1; } if (!valB) { return 1; } debugDev(`CHECKING SUBFIELD '${subfieldCode}': '${valA}' vs '${valB}'`); if (valA < valB) { return -1; } if (valB < valA) { return 1; } return scoreSubfieldsAlphabetically(remainingSubfieldCodes); } if (fieldA.tag === fieldB.tag) { if (!(fieldA.tag in tagToSortingSubfields)) { return 0; } const subfieldsToCheck = tagToSortingSubfields[fieldA.tag]; const result = scoreSubfieldsAlphabetically(subfieldsToCheck); debugDev(`RESULT ${result}`); return result; } return 0; } function selectFirstValue(field, subcode) { return field.subfields.filter((subfield) => subcode === subfield.code).map((subfield) => subfield.value).slice(0, 1); } //# sourceMappingURL=marcFieldSort.js.map