diff --git a/src/interaction/main/mainLinks.js b/src/interaction/main/mainLinks.js
index 2c025b2bae3059510aba92ae98b74c37f660bc0b..19f1c3a13d25c94b604d343c9fdbd499cc9314c5 100644
--- a/src/interaction/main/mainLinks.js
+++ b/src/interaction/main/mainLinks.js
@@ -73,7 +73,7 @@ App.UI.View.mainLinks = function() {
 						trainees.push(App.UI.DOM.combineNodes(App.UI.DOM.makeElement("span", SlaveFullName(trainee), "slave-name"),
 							` to ${V.personalAttention[i].trainingRegimen}`));
 					});
-					fragment.append(App.UI.DOM.arrayToList(trainees));
+					fragment.append(App.UI.DOM.toSentence(trainees));
 
 					fragment.append(` this week.`);
 				}
diff --git a/src/js/salon.js b/src/js/salon.js
index cd10fc15581c7ee9d9518f5d25f8795d155000e0..97336e536912f7ab25130de16962b814b53599ec 100644
--- a/src/js/salon.js
+++ b/src/js/salon.js
@@ -60,7 +60,7 @@ App.Medicine.Modification.eyeSelector = function(entity, cheat = false) {
 
 		const div = document.createElement("div");
 		div.classList.add("choices");
-		div.append(name, App.UI.DOM.arrayToList(links, " | ", " | "));
+		div.append(name, App.UI.DOM.generateLinksStrip(links));
 		return div;
 	}
 
@@ -204,7 +204,7 @@ App.Medicine.Modification.eyeSelector = function(entity, cheat = false) {
 			links.push(removeLink("Remove both glass eyes", () => eyeSurgery(entity, "both", "remove")));
 		}
 		if (links.length > 0) {
-			removeDiv.append(App.UI.DOM.arrayToList(links, " | ", " | "));
+			removeDiv.append(App.UI.DOM.generateLinksStrip(links));
 		}
 	}
 
diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js
index a2e6e8f1d049a8c63763a389be1bb5a293ee77ec..0dad38b0a0e8c8692213a4ae627852e0c93e73a0 100644
--- a/src/js/slaveListing.js
+++ b/src/js/slaveListing.js
@@ -567,13 +567,13 @@ App.UI.SlaveList.sortingLinks = function(passage) {
 	let order = ["devotion", "name", "assignment", "seniority", "actualAge", "visualAge", "physicalAge", "weeklyIncome", "health", "weight", "muscles", "intelligence", "sexDrive", "pregnancy"]
 		.map(so => V.sortSlavesBy !== so ?
 			App.UI.DOM.passageLink(textify(so), passage, () => { V.sortSlavesBy = so; }) : textify(so));
-	innerDiv.append(App.UI.DOM.arrayToList(order, " | ", " | "));
+	innerDiv.append(App.UI.DOM.generateLinksStrip(order));
 	outerDiv.append(innerDiv);
 
 	innerDiv = App.UI.DOM.makeElement("div", "Sort direction: ", "indent");
 	order = ["descending", "ascending"].map(so => V.sortSlavesOrder !== so ?
 		App.UI.DOM.passageLink(textify(so), passage, () => { V.sortSlavesOrder = so; }) : textify(so));
-	innerDiv.append(App.UI.DOM.arrayToList(order, " | ", " | "));
+	innerDiv.append(App.UI.DOM.generateLinksStrip(order));
 	outerDiv.append(innerDiv);
 
 	return outerDiv;
@@ -1026,7 +1026,7 @@ App.UI.SlaveList.penthousePage = function() {
 		for (const tab of tabs) {
 			links.push(App.UI.tabBar.tabButton(tab.tabName, tab.caption, true));
 		}
-		div.append(App.UI.DOM.arrayToList(links, " | ", " | "));
+		div.append(App.UI.DOM.generateLinksStrip(links));
 	} else {
 		for (const tab of tabs) {
 			const button = App.UI.tabBar.tabButton(tab.tabName, tab.caption);
diff --git a/src/js/utilsDOM.js b/src/js/utilsDOM.js
index d11b42132c043a9032d435b6f93cd7c7f8481817..7c70d8a71398b1ac1e3f920856a3d705878a7cfe 100644
--- a/src/js/utilsDOM.js
+++ b/src/js/utilsDOM.js
@@ -285,29 +285,33 @@ App.UI.DOM.colorInput = function(defaultValue, onEnter) {
 /**
  * Concats an array of DOM nodes or strings into a human readable list.
  *
- * @param {Array<Node|string>} content
- * @param {string} [delimiter]
- * @param {string} [lastDelimiter]
- * @returns {Node|string}
+ * @param {Iterable<Node|string>} content
+ * @param {Node|string} [delimiter]
+ * @param {Node|string} [lastDelimiter]
+ * @returns {Node}
  */
-App.UI.DOM.arrayToList = function(content, delimiter = ", ", lastDelimiter = " and ") {
-	if (content.length === 0) {
-		return "none";
-	}
-	if (content.length === 1) {
-		return content[0];
-	}
-	const fragment = document.createDocumentFragment();
-	const last = content.pop();
-	for (let i = 0; i < content.length; i++) {
-		fragment.append(content[i]);
-		if (i < content.length - 1) {
-			fragment.append(delimiter);
+App.UI.DOM.toSentence = function(content, delimiter = ", ", lastDelimiter = " and ") {
+	const itr = content[Symbol.iterator]();
+	let output = document.createDocumentFragment();
+	let result = itr.next();
+	if (!result.done) {
+		// output first element
+		output.append(result.value);
+		result = itr.next();
+		if (!result.done) {
+			// output elements (1...n-1)
+			let previous = result.value;
+			result = itr.next();
+			while (!result.done) {
+				output.append(delimiter, previous);
+				previous = result.value;
+				result = itr.next();
+			}
+			// output final element
+			output.append(lastDelimiter, previous);
 		}
 	}
-	content.push(last); // don't leave the array modified
-	fragment.append(lastDelimiter, last);
-	return fragment;
+	return output;
 };
 
 /**
@@ -352,16 +356,16 @@ App.Utils.htmlToElement = function(text) {
 
 /**
  * Show a list of links (or disabled links) as a delimited strip
- * @param {Node[]} links
+ * @param {Array<Node|string>} links
  * @returns {HTMLUListElement}
  */
 App.UI.DOM.generateLinksStrip = function(links) {
 	const strip = document.createElement('ul');
 	strip.className = "choicesStrip";
 
-	links.reduce((list, lnk) => {
+	links.reduce((/** @type {HTMLUListElement} */ list, lnk) => {
 		const li = document.createElement("li");
-		li.appendChild(lnk);
+		li.append(lnk);
 		list.appendChild(li);
 		return list;
 	}, strip);
diff --git a/src/npc/startingGirls/startingGirlsPassage.js b/src/npc/startingGirls/startingGirlsPassage.js
index b99de039409290a317a5e334f4e972e08624c918..a7c4760516bf639bcbce084264c8f844e4423082 100644
--- a/src/npc/startingGirls/startingGirlsPassage.js
+++ b/src/npc/startingGirls/startingGirlsPassage.js
@@ -24,19 +24,8 @@ App.StartingGirls.passage = function() {
 		}
 	} else {
 		const pronoun = V.slaves.length > 1 ? "they" : getPronouns(V.slaves[0]).he;
-		const frag = document.createDocumentFragment();
-		for (let i = 0; i < V.slaves.length; ++i) {
-			if (i > 0 && i < V.slaves.length - 1) {
-				frag.append(`, `);
-			} else if (i > 0) {
-				frag.append(` and `);
-			}
-			frag.append(App.UI.DOM.slaveDescriptionDialog(V.slaves[i]));
-			if (i === V.slaves.length - 1) {
-				frag.append(`'s`);
-			}
-		}
-		r.push(frag, `records have been finalized; ${pronoun} will arrive with you when you take over your new arcology.`);
+		r.push(App.UI.DOM.combineNodes(App.UI.DOM.toSentence(V.slaves.map(s => App.UI.DOM.slaveDescriptionDialog(s))), "'s"));
+		r.push(`records have been finalized; ${pronoun} will arrive with you when you take over your new arcology.`);
 	}
 	r.push(App.UI.DOM.makeElement("div", "Current cash reserves can be found on the far left sidebar."));
 	App.Events.addNode(el, r, "p");