commit
message
[Text.SUBSTITUTE] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-12-01 04:50:02
stats
8 file(s) changed,
114 insertions(+),
6 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Text.js
src/Formulas/AllFormulas.ts
src/Formulas/Text.ts
tests/Formulas/TextTest.ts
tests/SheetFormulaTest.ts
1diff --git a/DOCS.md b/DOCS.md
2index 5777d37..f04a23c 100644
3--- a/DOCS.md
4+++ b/DOCS.md
5@@ -2510,3 +2510,15 @@
6 @param newText - The text which replaces text.
7 @constructor
8 ```
9+
10+### SUBSTITUTE
11+
12+```
13+ Substitutes new text for old text in a string.
14+@param text - The text in which text segments are to be exchanged.
15+@param searchFor - The text segment that is to be replaced (a number of times)
16+@param replaceWith - The text that is to replace the text segment.
17+@param occurrence - [OPTIONAL] - Indicates how many occurrences of the search text are to be replaced. If this parameter is missing, the search text is replaced throughout.
18+@returns {string}
19+@constructor
20+```
21diff --git a/TODO.md b/TODO.md
22index c608205..00fc034 100644
23--- a/TODO.md
24+++ b/TODO.md
25@@ -46,7 +46,6 @@ Many of these formulas can be written by allowing the Sheet and Parser to return
26 * REGEXEXTRACT - May be difficult considering language differences.
27 * REGEXMATCH - May be difficult considering language differences.
28 * REGEXREPLACE - May be difficult considering language differences.
29-* SUBSTITUTE
30
31 ### Other formulas to write
32 * CRITBINOM
33diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
34index 0a7ac0d..a041956 100644
35--- a/dist/Formulas/AllFormulas.js
36+++ b/dist/Formulas/AllFormulas.js
37@@ -239,6 +239,7 @@ exports.CLEAN = Text_1.CLEAN;
38 exports.MID = Text_1.MID;
39 exports.PROPER = Text_1.PROPER;
40 exports.REPLACE = Text_1.REPLACE;
41+exports.SUBSTITUTE = Text_1.SUBSTITUTE;
42 var Date_1 = require("./Date");
43 exports.DATE = Date_1.DATE;
44 exports.DATEVALUE = Date_1.DATEVALUE;
45diff --git a/dist/Formulas/Text.js b/dist/Formulas/Text.js
46index d1401d0..141bd6c 100644
47--- a/dist/Formulas/Text.js
48+++ b/dist/Formulas/Text.js
49@@ -922,3 +922,38 @@ var REPLACE = function (text, position, length, newText) {
50 return text.substr(0, position - 1) + newText + text.substr(position - 1 + length);
51 };
52 exports.REPLACE = REPLACE;
53+/**
54+ * Substitutes new text for old text in a string.
55+ * @param text - The text in which text segments are to be exchanged.
56+ * @param searchFor - The text segment that is to be replaced (a number of times)
57+ * @param replaceWith - The text that is to replace the text segment.
58+ * @param occurrence - [OPTIONAL] - Indicates how many occurrences of the search text are to be replaced. If this
59+ * parameter is missing, the search text is replaced throughout.
60+ * @returns {string}
61+ * @constructor
62+ */
63+var SUBSTITUTE = function (text, searchFor, replaceWith, occurrence) {
64+ ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 3, 4, "SUBSTITUTE");
65+ text = TypeConverter_1.TypeConverter.firstValueAsString(text);
66+ searchFor = TypeConverter_1.TypeConverter.firstValueAsString(searchFor);
67+ replaceWith = TypeConverter_1.TypeConverter.firstValueAsString(replaceWith);
68+ if (MoreUtils_1.isUndefined(occurrence)) {
69+ return text.replace(new RegExp(searchFor, 'g'), replaceWith);
70+ }
71+ occurrence = TypeConverter_1.TypeConverter.firstValueAsNumber(occurrence);
72+ if (occurrence < 0) {
73+ throw new Errors_1.ValueError("Function SUBSTITUTE parameter 4 value is " + occurrence
74+ + ", but should be greater than or equal to 0.");
75+ }
76+ var index = 0;
77+ var i = 0;
78+ while (text.indexOf(searchFor, index) > -1) {
79+ index = text.indexOf(searchFor, index);
80+ i++;
81+ if (i === occurrence) {
82+ return text.substring(0, index) + replaceWith + text.substring(index + searchFor.length);
83+ }
84+ }
85+ return text;
86+};
87+exports.SUBSTITUTE = SUBSTITUTE;
88diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
89index cdc6fc1..5305cb9 100644
90--- a/src/Formulas/AllFormulas.ts
91+++ b/src/Formulas/AllFormulas.ts
92@@ -246,7 +246,8 @@ import {
93 CLEAN,
94 MID,
95 PROPER,
96- REPLACE
97+ REPLACE,
98+ SUBSTITUTE
99 } from "./Text"
100 import {
101 DATE,
102@@ -553,5 +554,6 @@ export {
103 CLEAN,
104 MID,
105 PROPER,
106- REPLACE
107+ REPLACE,
108+ SUBSTITUTE
109 }
110\ No newline at end of file
111diff --git a/src/Formulas/Text.ts b/src/Formulas/Text.ts
112index a1f1e96..80db805 100644
113--- a/src/Formulas/Text.ts
114+++ b/src/Formulas/Text.ts
115@@ -956,6 +956,43 @@ let REPLACE = function (text, position, length, newText) {
116 return text.substr(0, position - 1) + newText + text.substr(position - 1 + length);
117 };
118
119+
120+/**
121+ * Substitutes new text for old text in a string.
122+ * @param text - The text in which text segments are to be exchanged.
123+ * @param searchFor - The text segment that is to be replaced (a number of times)
124+ * @param replaceWith - The text that is to replace the text segment.
125+ * @param occurrence - [OPTIONAL] - Indicates how many occurrences of the search text are to be replaced. If this
126+ * parameter is missing, the search text is replaced throughout.
127+ * @returns {string}
128+ * @constructor
129+ */
130+let SUBSTITUTE = function (text, searchFor, replaceWith, occurrence?) {
131+ ArgsChecker.checkLengthWithin(arguments, 3, 4, "SUBSTITUTE");
132+ text = TypeConverter.firstValueAsString(text);
133+ searchFor = TypeConverter.firstValueAsString(searchFor);
134+ replaceWith = TypeConverter.firstValueAsString(replaceWith);
135+
136+ if (isUndefined(occurrence)) {
137+ return text.replace(new RegExp(searchFor, 'g'), replaceWith);
138+ }
139+ occurrence = TypeConverter.firstValueAsNumber(occurrence);
140+ if (occurrence < 0) {
141+ throw new ValueError("Function SUBSTITUTE parameter 4 value is " + occurrence
142+ + ", but should be greater than or equal to 0.");
143+ }
144+ let index = 0;
145+ let i = 0;
146+ while (text.indexOf(searchFor, index) > -1) {
147+ index = text.indexOf(searchFor, index);
148+ i++;
149+ if (i === occurrence) {
150+ return text.substring(0, index) + replaceWith + text.substring(index + searchFor.length);
151+ }
152+ }
153+ return text;
154+};
155+
156 export {
157 ARABIC,
158 CHAR,
159@@ -980,5 +1017,6 @@ export {
160 CLEAN,
161 MID,
162 PROPER,
163- REPLACE
164+ REPLACE,
165+ SUBSTITUTE
166 }
167\ No newline at end of file
168diff --git a/tests/Formulas/TextTest.ts b/tests/Formulas/TextTest.ts
169index dc8ebc1..b0b5441 100644
170--- a/tests/Formulas/TextTest.ts
171+++ b/tests/Formulas/TextTest.ts
172@@ -22,7 +22,8 @@ import {
173 CLEAN,
174 MID,
175 PROPER,
176- REPLACE
177+ REPLACE,
178+ SUBSTITUTE
179 } from "../../src/Formulas/Text";
180 import * as ERRORS from "../../src/Errors";
181 import {
182@@ -574,3 +575,18 @@ test("PROPER", function(){
183 REPLACE("Hey there", 1, -1, "Hello")
184 }, ERRORS.VALUE_ERROR);
185 });
186+
187+test("SUBSTITUTE", function(){
188+ assertEquals(SUBSTITUTE("Hey darkness my old friend", "Hey", "Hello"), "Hello darkness my old friend");
189+ assertEquals(SUBSTITUTE("Hey darkness my old friend... Hey.", "Hey", "Hello"), "Hello darkness my old friend... Hello.");
190+ assertEquals(SUBSTITUTE("Hey darkness my old friend... Hey.", "Hey", "Hello", 1), "Hello darkness my old friend... Hey.");
191+ catchAndAssertEquals(function () {
192+ SUBSTITUTE.apply(this, ["a", "b"]);
193+ }, ERRORS.NA_ERROR);
194+ catchAndAssertEquals(function () {
195+ SUBSTITUTE.apply(this, ["a", "b", "c", 1, 2]);
196+ }, ERRORS.NA_ERROR);
197+ catchAndAssertEquals(function () {
198+ SUBSTITUTE("Hey there", "hey", "hello", -1);
199+ }, ERRORS.VALUE_ERROR);
200+});
201diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
202index 1d943f0..bcaa3ef 100644
203--- a/tests/SheetFormulaTest.ts
204+++ b/tests/SheetFormulaTest.ts
205@@ -1089,10 +1089,14 @@ test("Sheet PROPER", function(){
206 assertFormulaEquals('=PROPER("hey there")', "Hey There");
207 });
208
209-test("Sheet PROPER", function(){
210+test("Sheet REPLACE", function(){
211 assertFormulaEquals('=REPLACE("Hey there", 1, 3, "Hello")', "Hello there");
212 });
213
214+test("Sheet SUBSTITUTE", function(){
215+ assertFormulaEquals('=SUBSTITUTE("Hey darkness my old friend", "Hey", "Hello")', "Hello darkness my old friend");
216+});
217+
218 test("Sheet parsing error", function(){
219 assertFormulaEqualsError('= 10e', PARSE_ERROR);
220 assertFormulaEqualsError('= SUM(', PARSE_ERROR);