Skip to content

Commit

Permalink
Merge pull request #213 from opensource9ja/fix/str-bug
Browse files Browse the repository at this point in the history
Fixes #181 Bug in str accessor when NaN values are present
  • Loading branch information
risenW authored May 30, 2021
2 parents 7af31b0 + 88828a9 commit fb797a6
Show file tree
Hide file tree
Showing 13 changed files with 543 additions and 245 deletions.
2 changes: 1 addition & 1 deletion danfojs-browser/lib/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion danfojs-browser/lib/bundle.js.map

Large diffs are not rendered by default.

18 changes: 6 additions & 12 deletions danfojs-browser/src/core/series.js
Original file line number Diff line number Diff line change
Expand Up @@ -1195,20 +1195,14 @@ export class Series extends NDframe {


/**
* Exposes numerous string methods to manipulate Series
*/
* Exposes numerous string methods to manipulate Series of type string
*/
get str() {
let values = this.values;
if (this.dtypes[0] != "string") {
let new_vals = [];
//convert each value in array to string
values.forEach((val) => {
new_vals.push(String(val));
});
let sf = new Series(new_vals, { columns: this.column_names, index: this.index });
return new Str(sf);
if (this.dtypes[0] == "string") {
return new Str(this);
} else {
throw new Error("Cannot call accessor str on non-string type");
}
return new Str(this);

}

Expand Down
143 changes: 115 additions & 28 deletions danfojs-browser/src/core/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ export class Str {
toLowerCase() {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.toLowerCase());
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.toLowerCase());
}

});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -29,7 +34,12 @@ export class Str {
toUpperCase() {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.toUpperCase());
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.toUpperCase());
}

});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -42,10 +52,15 @@ export class Str {
capitalize() {
let new_arr = [];
this.array.map((val) => {
let f_char = val.slice(0, 1);
let l_char = val.slice(1);
let new_str = `${f_char.toUpperCase()}${l_char.toLowerCase()}`;
new_arr.push(new_str);
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
let f_char = val.slice(0, 1);
let l_char = val.slice(1);
let new_str = `${f_char.toUpperCase()}${l_char.toLowerCase()}`;
new_arr.push(new_str);
}

});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -60,7 +75,11 @@ export class Str {
charAt(index = 0) {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.charAt(index));
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.charAt(index));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand Down Expand Up @@ -94,10 +113,18 @@ export class Str {

this.array.map((val) => {
if (position == 1) {
new_arr.push(val.concat(other));
if (isNaN(val) && typeof val != "string") {
new_arr.push(String(val).concat(other));
} else {
new_arr.push(val.concat(other));
}

} else {
new_arr.push(other.concat(val));
if (isNaN(val) && typeof val != "string") {
new_arr.push(other.concat(String(val)));
} else {
new_arr.push(other.concat(val));
}
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
Expand All @@ -114,8 +141,12 @@ export class Str {
*/
startsWith(str = "") {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.startsWith(str));
this.array.forEach((val) => {
if (isNaN(val) && typeof val != "string") {
new_arr.push(false);
} else {
new_arr.push(val.startsWith(str));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -129,7 +160,11 @@ export class Str {
endsWith(str = "") {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.endsWith(str));
if (isNaN(val) && typeof val != "string") {
new_arr.push(false);
} else {
new_arr.push(val.endsWith(str));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -143,7 +178,11 @@ export class Str {
includes(str = "") {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.includes(str));
if (isNaN(val) && typeof val != "string") {
new_arr.push(false);
} else {
new_arr.push(val.includes(str));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -157,7 +196,11 @@ export class Str {
indexOf(str = "") {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.indexOf(str));
if (isNaN(val) && typeof val != "string") {
new_arr.push(-1);
} else {
new_arr.push(val.indexOf(str));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -171,7 +214,11 @@ export class Str {
lastIndexOf(str = "") {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.lastIndexOf(str));
if (isNaN(val) && typeof val != "string") {
new_arr.push(-1);
} else {
new_arr.push(val.lastIndexOf(str));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -187,7 +234,11 @@ export class Str {
replace(searchValue = "", replaceValue = "") {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.replace(searchValue, replaceValue));
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.replace(searchValue, replaceValue));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -201,7 +252,11 @@ export class Str {
repeat(num = 1) {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.repeat(num));
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.repeat(num));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -216,7 +271,11 @@ export class Str {
search(str = "") {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.search(str));
if (isNaN(val) && typeof val != "string") {
new_arr.push(-1);
} else {
new_arr.push(val.search(str));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -231,7 +290,11 @@ export class Str {
slice(startIndex = 0, endIndex = 1) {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.slice(startIndex, endIndex));
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.slice(startIndex, endIndex));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -246,7 +309,11 @@ export class Str {
split(splitVal = " ") {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.split(splitVal));
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.split(splitVal));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -261,7 +328,11 @@ export class Str {
substr(startIndex = 0, num = 1) {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.substr(startIndex, num));
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.substr(startIndex, num));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -276,7 +347,11 @@ export class Str {
substring(startIndex = 0, endIndex = 1) {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.substring(startIndex, endIndex));
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.substring(startIndex, endIndex));
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -289,7 +364,11 @@ export class Str {
trim() {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.trim());
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.trim());
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -304,10 +383,14 @@ export class Str {
join(valToJoin = "", joinChar = " ") {
let new_arr = [];
this.array.map((val) => {
let l_char = val;
let r_char = valToJoin;
let new_char = `${l_char}${joinChar}${r_char}`;
new_arr.push(new_char);
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
let l_char = val;
let r_char = valToJoin;
let new_char = `${l_char}${joinChar}${r_char}`;
new_arr.push(new_char);
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand All @@ -320,7 +403,11 @@ export class Str {
len() {
let new_arr = [];
this.array.map((val) => {
new_arr.push(val.length);
if (isNaN(val) && typeof val != "string") {
new_arr.push(val);
} else {
new_arr.push(val.length);
}
});
let sf = this.__create_new_sf_from(new_arr, this.series);
return sf;
Expand Down
24 changes: 24 additions & 0 deletions danfojs-browser/tests/core/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -2352,4 +2352,28 @@ describe("DataFrame", function () {

});
});
describe("Str", function () {
it("Str (startsWith) works for columns selected from a DF", function () {
let data = {
"Name": [ "Apples", "Bake", "Application", undefined ],
"Count": [ 2, 5, 4, 10 ],
"Price": [ 200, 300, 40, 250 ]
};

let df = new dfd.DataFrame(data);
let name_sf = df['Name'];
assert.deepEqual(name_sf.str.startsWith("App").values, [ true, false, true, false ]);
});
it("Str (toLowerCase) works for columns selected from a DF", function () {
let data = {
"Name": [ "Apples", "Bake", "Application", undefined ],
"Count": [ 2, 5, 4, 10 ],
"Price": [ 200, 300, 40, 250 ]
};

let df = new dfd.DataFrame(data);
let name_sf = df['Name'];
assert.deepEqual(name_sf.str.toLowerCase().values, [ "apples", "bake", "application", NaN ]);
});
});
});
12 changes: 9 additions & 3 deletions danfojs-browser/tests/core/series.js
Original file line number Diff line number Diff line change
Expand Up @@ -1134,11 +1134,17 @@ describe("Series", function () {
assert.deepEqual(sf.str.charAt(2).values, res);
});

it("Returns the concat of numeric series", function () {
it("Throws error on concat of numeric series", function () {
let data = [ 1, 2, 3, 4, 5, 6 ];
let res = [ "120", "220", "320", "420", "520", "620" ];
let sf = new dfd.Series(data);
assert.deepEqual(sf.str.concat("20", 1).values, res);
assert.throws(
() => {
sf.str.concat("20", 1);
},
Error,
"Cannot call accessor str on non-string type"
);

});
});

Expand Down
18 changes: 4 additions & 14 deletions danfojs-node/dist/core/series.js
Original file line number Diff line number Diff line change
Expand Up @@ -961,21 +961,11 @@ class Series extends _generic.default {
}

get str() {
let values = this.values;

if (this.dtypes[0] != "string") {
let new_vals = [];
values.forEach(val => {
new_vals.push(String(val));
});
let sf = new Series(new_vals, {
columns: this.column_names,
index: this.index
});
return new _strings.Str(sf);
if (this.dtypes[0] == "string") {
return new _strings.Str(this);
} else {
throw new Error("Cannot call accessor str on non-string type");
}

return new _strings.Str(this);
}

get dt() {
Expand Down
Loading

0 comments on commit fb797a6

Please sign in to comment.