Skip to content

Commit fb797a6

Browse files
authored
Merge pull request #213 from opensource9ja/fix/str-bug
Fixes #181 Bug in str accessor when NaN values are present
2 parents 7af31b0 + 88828a9 commit fb797a6

File tree

13 files changed

+543
-245
lines changed

13 files changed

+543
-245
lines changed

danfojs-browser/lib/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

danfojs-browser/lib/bundle.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

danfojs-browser/src/core/series.js

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,20 +1195,14 @@ export class Series extends NDframe {
11951195

11961196

11971197
/**
1198-
* Exposes numerous string methods to manipulate Series
1199-
*/
1198+
* Exposes numerous string methods to manipulate Series of type string
1199+
*/
12001200
get str() {
1201-
let values = this.values;
1202-
if (this.dtypes[0] != "string") {
1203-
let new_vals = [];
1204-
//convert each value in array to string
1205-
values.forEach((val) => {
1206-
new_vals.push(String(val));
1207-
});
1208-
let sf = new Series(new_vals, { columns: this.column_names, index: this.index });
1209-
return new Str(sf);
1201+
if (this.dtypes[0] == "string") {
1202+
return new Str(this);
1203+
} else {
1204+
throw new Error("Cannot call accessor str on non-string type");
12101205
}
1211-
return new Str(this);
12121206

12131207
}
12141208

danfojs-browser/src/core/strings.js

Lines changed: 115 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ export class Str {
1616
toLowerCase() {
1717
let new_arr = [];
1818
this.array.map((val) => {
19-
new_arr.push(val.toLowerCase());
19+
if (isNaN(val) && typeof val != "string") {
20+
new_arr.push(val);
21+
} else {
22+
new_arr.push(val.toLowerCase());
23+
}
24+
2025
});
2126
let sf = this.__create_new_sf_from(new_arr, this.series);
2227
return sf;
@@ -29,7 +34,12 @@ export class Str {
2934
toUpperCase() {
3035
let new_arr = [];
3136
this.array.map((val) => {
32-
new_arr.push(val.toUpperCase());
37+
if (isNaN(val) && typeof val != "string") {
38+
new_arr.push(val);
39+
} else {
40+
new_arr.push(val.toUpperCase());
41+
}
42+
3343
});
3444
let sf = this.__create_new_sf_from(new_arr, this.series);
3545
return sf;
@@ -42,10 +52,15 @@ export class Str {
4252
capitalize() {
4353
let new_arr = [];
4454
this.array.map((val) => {
45-
let f_char = val.slice(0, 1);
46-
let l_char = val.slice(1);
47-
let new_str = `${f_char.toUpperCase()}${l_char.toLowerCase()}`;
48-
new_arr.push(new_str);
55+
if (isNaN(val) && typeof val != "string") {
56+
new_arr.push(val);
57+
} else {
58+
let f_char = val.slice(0, 1);
59+
let l_char = val.slice(1);
60+
let new_str = `${f_char.toUpperCase()}${l_char.toLowerCase()}`;
61+
new_arr.push(new_str);
62+
}
63+
4964
});
5065
let sf = this.__create_new_sf_from(new_arr, this.series);
5166
return sf;
@@ -60,7 +75,11 @@ export class Str {
6075
charAt(index = 0) {
6176
let new_arr = [];
6277
this.array.map((val) => {
63-
new_arr.push(val.charAt(index));
78+
if (isNaN(val) && typeof val != "string") {
79+
new_arr.push(val);
80+
} else {
81+
new_arr.push(val.charAt(index));
82+
}
6483
});
6584
let sf = this.__create_new_sf_from(new_arr, this.series);
6685
return sf;
@@ -94,10 +113,18 @@ export class Str {
94113

95114
this.array.map((val) => {
96115
if (position == 1) {
97-
new_arr.push(val.concat(other));
116+
if (isNaN(val) && typeof val != "string") {
117+
new_arr.push(String(val).concat(other));
118+
} else {
119+
new_arr.push(val.concat(other));
120+
}
98121

99122
} else {
100-
new_arr.push(other.concat(val));
123+
if (isNaN(val) && typeof val != "string") {
124+
new_arr.push(other.concat(String(val)));
125+
} else {
126+
new_arr.push(other.concat(val));
127+
}
101128
}
102129
});
103130
let sf = this.__create_new_sf_from(new_arr, this.series);
@@ -114,8 +141,12 @@ export class Str {
114141
*/
115142
startsWith(str = "") {
116143
let new_arr = [];
117-
this.array.map((val) => {
118-
new_arr.push(val.startsWith(str));
144+
this.array.forEach((val) => {
145+
if (isNaN(val) && typeof val != "string") {
146+
new_arr.push(false);
147+
} else {
148+
new_arr.push(val.startsWith(str));
149+
}
119150
});
120151
let sf = this.__create_new_sf_from(new_arr, this.series);
121152
return sf;
@@ -129,7 +160,11 @@ export class Str {
129160
endsWith(str = "") {
130161
let new_arr = [];
131162
this.array.map((val) => {
132-
new_arr.push(val.endsWith(str));
163+
if (isNaN(val) && typeof val != "string") {
164+
new_arr.push(false);
165+
} else {
166+
new_arr.push(val.endsWith(str));
167+
}
133168
});
134169
let sf = this.__create_new_sf_from(new_arr, this.series);
135170
return sf;
@@ -143,7 +178,11 @@ export class Str {
143178
includes(str = "") {
144179
let new_arr = [];
145180
this.array.map((val) => {
146-
new_arr.push(val.includes(str));
181+
if (isNaN(val) && typeof val != "string") {
182+
new_arr.push(false);
183+
} else {
184+
new_arr.push(val.includes(str));
185+
}
147186
});
148187
let sf = this.__create_new_sf_from(new_arr, this.series);
149188
return sf;
@@ -157,7 +196,11 @@ export class Str {
157196
indexOf(str = "") {
158197
let new_arr = [];
159198
this.array.map((val) => {
160-
new_arr.push(val.indexOf(str));
199+
if (isNaN(val) && typeof val != "string") {
200+
new_arr.push(-1);
201+
} else {
202+
new_arr.push(val.indexOf(str));
203+
}
161204
});
162205
let sf = this.__create_new_sf_from(new_arr, this.series);
163206
return sf;
@@ -171,7 +214,11 @@ export class Str {
171214
lastIndexOf(str = "") {
172215
let new_arr = [];
173216
this.array.map((val) => {
174-
new_arr.push(val.lastIndexOf(str));
217+
if (isNaN(val) && typeof val != "string") {
218+
new_arr.push(-1);
219+
} else {
220+
new_arr.push(val.lastIndexOf(str));
221+
}
175222
});
176223
let sf = this.__create_new_sf_from(new_arr, this.series);
177224
return sf;
@@ -187,7 +234,11 @@ export class Str {
187234
replace(searchValue = "", replaceValue = "") {
188235
let new_arr = [];
189236
this.array.map((val) => {
190-
new_arr.push(val.replace(searchValue, replaceValue));
237+
if (isNaN(val) && typeof val != "string") {
238+
new_arr.push(val);
239+
} else {
240+
new_arr.push(val.replace(searchValue, replaceValue));
241+
}
191242
});
192243
let sf = this.__create_new_sf_from(new_arr, this.series);
193244
return sf;
@@ -201,7 +252,11 @@ export class Str {
201252
repeat(num = 1) {
202253
let new_arr = [];
203254
this.array.map((val) => {
204-
new_arr.push(val.repeat(num));
255+
if (isNaN(val) && typeof val != "string") {
256+
new_arr.push(val);
257+
} else {
258+
new_arr.push(val.repeat(num));
259+
}
205260
});
206261
let sf = this.__create_new_sf_from(new_arr, this.series);
207262
return sf;
@@ -216,7 +271,11 @@ export class Str {
216271
search(str = "") {
217272
let new_arr = [];
218273
this.array.map((val) => {
219-
new_arr.push(val.search(str));
274+
if (isNaN(val) && typeof val != "string") {
275+
new_arr.push(-1);
276+
} else {
277+
new_arr.push(val.search(str));
278+
}
220279
});
221280
let sf = this.__create_new_sf_from(new_arr, this.series);
222281
return sf;
@@ -231,7 +290,11 @@ export class Str {
231290
slice(startIndex = 0, endIndex = 1) {
232291
let new_arr = [];
233292
this.array.map((val) => {
234-
new_arr.push(val.slice(startIndex, endIndex));
293+
if (isNaN(val) && typeof val != "string") {
294+
new_arr.push(val);
295+
} else {
296+
new_arr.push(val.slice(startIndex, endIndex));
297+
}
235298
});
236299
let sf = this.__create_new_sf_from(new_arr, this.series);
237300
return sf;
@@ -246,7 +309,11 @@ export class Str {
246309
split(splitVal = " ") {
247310
let new_arr = [];
248311
this.array.map((val) => {
249-
new_arr.push(val.split(splitVal));
312+
if (isNaN(val) && typeof val != "string") {
313+
new_arr.push(val);
314+
} else {
315+
new_arr.push(val.split(splitVal));
316+
}
250317
});
251318
let sf = this.__create_new_sf_from(new_arr, this.series);
252319
return sf;
@@ -261,7 +328,11 @@ export class Str {
261328
substr(startIndex = 0, num = 1) {
262329
let new_arr = [];
263330
this.array.map((val) => {
264-
new_arr.push(val.substr(startIndex, num));
331+
if (isNaN(val) && typeof val != "string") {
332+
new_arr.push(val);
333+
} else {
334+
new_arr.push(val.substr(startIndex, num));
335+
}
265336
});
266337
let sf = this.__create_new_sf_from(new_arr, this.series);
267338
return sf;
@@ -276,7 +347,11 @@ export class Str {
276347
substring(startIndex = 0, endIndex = 1) {
277348
let new_arr = [];
278349
this.array.map((val) => {
279-
new_arr.push(val.substring(startIndex, endIndex));
350+
if (isNaN(val) && typeof val != "string") {
351+
new_arr.push(val);
352+
} else {
353+
new_arr.push(val.substring(startIndex, endIndex));
354+
}
280355
});
281356
let sf = this.__create_new_sf_from(new_arr, this.series);
282357
return sf;
@@ -289,7 +364,11 @@ export class Str {
289364
trim() {
290365
let new_arr = [];
291366
this.array.map((val) => {
292-
new_arr.push(val.trim());
367+
if (isNaN(val) && typeof val != "string") {
368+
new_arr.push(val);
369+
} else {
370+
new_arr.push(val.trim());
371+
}
293372
});
294373
let sf = this.__create_new_sf_from(new_arr, this.series);
295374
return sf;
@@ -304,10 +383,14 @@ export class Str {
304383
join(valToJoin = "", joinChar = " ") {
305384
let new_arr = [];
306385
this.array.map((val) => {
307-
let l_char = val;
308-
let r_char = valToJoin;
309-
let new_char = `${l_char}${joinChar}${r_char}`;
310-
new_arr.push(new_char);
386+
if (isNaN(val) && typeof val != "string") {
387+
new_arr.push(val);
388+
} else {
389+
let l_char = val;
390+
let r_char = valToJoin;
391+
let new_char = `${l_char}${joinChar}${r_char}`;
392+
new_arr.push(new_char);
393+
}
311394
});
312395
let sf = this.__create_new_sf_from(new_arr, this.series);
313396
return sf;
@@ -320,7 +403,11 @@ export class Str {
320403
len() {
321404
let new_arr = [];
322405
this.array.map((val) => {
323-
new_arr.push(val.length);
406+
if (isNaN(val) && typeof val != "string") {
407+
new_arr.push(val);
408+
} else {
409+
new_arr.push(val.length);
410+
}
324411
});
325412
let sf = this.__create_new_sf_from(new_arr, this.series);
326413
return sf;

danfojs-browser/tests/core/frame.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,4 +2352,28 @@ describe("DataFrame", function () {
23522352

23532353
});
23542354
});
2355+
describe("Str", function () {
2356+
it("Str (startsWith) works for columns selected from a DF", function () {
2357+
let data = {
2358+
"Name": [ "Apples", "Bake", "Application", undefined ],
2359+
"Count": [ 2, 5, 4, 10 ],
2360+
"Price": [ 200, 300, 40, 250 ]
2361+
};
2362+
2363+
let df = new dfd.DataFrame(data);
2364+
let name_sf = df['Name'];
2365+
assert.deepEqual(name_sf.str.startsWith("App").values, [ true, false, true, false ]);
2366+
});
2367+
it("Str (toLowerCase) works for columns selected from a DF", function () {
2368+
let data = {
2369+
"Name": [ "Apples", "Bake", "Application", undefined ],
2370+
"Count": [ 2, 5, 4, 10 ],
2371+
"Price": [ 200, 300, 40, 250 ]
2372+
};
2373+
2374+
let df = new dfd.DataFrame(data);
2375+
let name_sf = df['Name'];
2376+
assert.deepEqual(name_sf.str.toLowerCase().values, [ "apples", "bake", "application", NaN ]);
2377+
});
2378+
});
23552379
});

danfojs-browser/tests/core/series.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,11 +1134,17 @@ describe("Series", function () {
11341134
assert.deepEqual(sf.str.charAt(2).values, res);
11351135
});
11361136

1137-
it("Returns the concat of numeric series", function () {
1137+
it("Throws error on concat of numeric series", function () {
11381138
let data = [ 1, 2, 3, 4, 5, 6 ];
1139-
let res = [ "120", "220", "320", "420", "520", "620" ];
11401139
let sf = new dfd.Series(data);
1141-
assert.deepEqual(sf.str.concat("20", 1).values, res);
1140+
assert.throws(
1141+
() => {
1142+
sf.str.concat("20", 1);
1143+
},
1144+
Error,
1145+
"Cannot call accessor str on non-string type"
1146+
);
1147+
11421148
});
11431149
});
11441150

danfojs-node/dist/core/series.js

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -961,21 +961,11 @@ class Series extends _generic.default {
961961
}
962962

963963
get str() {
964-
let values = this.values;
965-
966-
if (this.dtypes[0] != "string") {
967-
let new_vals = [];
968-
values.forEach(val => {
969-
new_vals.push(String(val));
970-
});
971-
let sf = new Series(new_vals, {
972-
columns: this.column_names,
973-
index: this.index
974-
});
975-
return new _strings.Str(sf);
964+
if (this.dtypes[0] == "string") {
965+
return new _strings.Str(this);
966+
} else {
967+
throw new Error("Cannot call accessor str on non-string type");
976968
}
977-
978-
return new _strings.Str(this);
979969
}
980970

981971
get dt() {

0 commit comments

Comments
 (0)