Reputation: 41
Im trying create my own substring method in JS
function substr(string, p1 = 0, p2 = string.length) {
if (string.length === 0 || p2 < 0 || p1 > p2) return '';
const p11 = p1 <= 0 ? 0 : p1
let p22 = p2 > string.length ? string.length : p2
const str = string.split('').reduce((acc, item, i) => {
if (i >= p11 && i < p22) {
console.log('i:', i)
return acc.concat(item)
}
return acc
}, '');
console.log('inside', str)
return str
}
when Im test this code I have an error
expect(substr('abba', 1, 0)).toEqual(''); // pass
expect(substr('abba', 0, 1)).toEqual('a'); // pass
expect(substr('abba', 0, 1)).toEqual('a'); // pass
expect(substr('abba', 1, 2)).toEqual('bb'); // failed
How I can fix my code to pass tests?
Upvotes: 0
Views: 350
Reputation: 3627
There is your code example:
1 function substr(string, p1 = 0, p2 = string.length) {
2 if (string.length === 0 || p2 < 0 || p1 > p2) return '';
3 const p11 = p1 <= 0 ? 0 : p1
4 let p22 = p2 > string.length ? string.length : p2
5 const str = string.split('').reduce((acc, item, i) => {
6 if (i >= p11 && i < p22) {
7 console.log('i:', i)
8 return acc.concat(item)
9 }
10 return acc
11 }, '');
12
13 console.log('inside', str)
14 return str
15 }
There are multiple mistakes in your code. You are still learning. That's no problem – everyone has started somehow. Let's name the mistakes:
On the line 2, there is p1 > p2
. That does not make sense. You do not want to return empty string if the distance between string start and the substring start is greater that the maximum substring length.
Your variable names do not make sense. Try using names like startpos
or length
instead of names like p1
or p2
.
And the third thing I found is that your substring function returns substring between positions p1
and p2
, unlike the JS's builtin String.prototype.substr
which returns substring between p1
and p1+p2
.
Try it this way:
function substr(string, start, length = string.length) {
let outStr = '';
for (let pos = start;
pos < start + length && pos < string.length;
pos++) {
outStr += string[pos];
}
return outStr;
}
function expect(actual) {
return {
'toEqual': function (expected) {
if (actual == expected) {
document.body.innerText += `“${actual}” == “${expected}” (pass)\n`;
} else {
document.body.innerText += `“${actual}” /= “${expected}” (fail)\n`;
}
},
};
}
expect(substr('abba', 1, 0)).toEqual('');
expect(substr('abba', 0, 1)).toEqual('a');
expect(substr('abba', 0, 1)).toEqual('a');
expect(substr('abba', 1, 2)).toEqual('bb');
I think that using split and reduce for this is overkill. But if you want to use it, there is the code in the “pure functional style”, but it is inefficient, because it needs string.length
steps instead of length
steps to compute the result.
function substr(string, start, length = string.length) {
return string
.split('') // split between every character
.reduce((head, char, index) =>
(index >= start && head.length < length) // if we reached the substring start and there “is space” in the substring,
? head + char // append another character
: head, // else keep the substring
''); // start with empty substring
}
function expect(actual) {
return {
'toEqual': function (expected) {
if (actual == expected) {
document.body.innerText += `“${actual}” == “${expected}” (pass)\n`;
} else {
document.body.innerText += `“${actual}” /= “${expected}” (fail)\n`;
}
},
};
}
expect(substr('abba', 1, 0)).toEqual('');
expect(substr('abba', 0, 1)).toEqual('a');
expect(substr('abba', 0, 1)).toEqual('a');
expect(substr('abba', 1, 2)).toEqual('bb');
You should also have better test cases. Write test cases as if wou would teach someone to use your routines. The test cases can be important for understanding complex code. For example, take you favorite sentence and test the function using it. It will be easier to understand the test case the next time you see the code.
Upvotes: 2