Reputation: 2561
Following is the code which is working fine but I am interested if I can make this code more efficient and reduce the number of lines in my replacementCountryLanguageCode
method using ES6 ?
My concern is about using if else if
statements as somewhere I read that they are not efficient (I don't remember the source and may be the context was different, so apologies if that is the case with if else if).
var url1 = "factory/news/fr/fr";
var url2 = "/factory/news/uk/en";
var url3 = "/region/factory/news/in/hi";
const replacementCountryLanguageCode = (url, countryCode, languageCode) => {
const splitUrl = url.split("/");
const splitUrlLength = splitUrl.length;
let a = [];
for( i= splitUrlLength-1; i >= 0; i--) {
if(i === splitUrlLength-1) {
a[splitUrlLength-1] = languageCode;
}
else if(i === splitUrlLength-2) {
a[splitUrlLength-2] = countryCode;
} else {
a[i] = splitUrl[i]
}
}
const modifiedUrl = a.join("/");
return modifiedUrl;
}
console.log( replacementCountryLanguageCode(url1, 'au', 'en') );
// Should return "factory/news/au/en"
console.log( replacementCountryLanguageCode(url2, 'fr', 'fr') );
// Should return "/factory/news/fr/fr"
console.log( replacementCountryLanguageCode(url3, 'es', 'es') );
// Should return "/region/factory/news/es/es"
Upvotes: 1
Views: 66
Reputation: 664970
First of all, there's no good reason to put those if
statements inside the loop. You could just as easily do
if (splitUrlLength-1 >= 0) {
a[splitUrlLength-1] = languageCode;
}
if (splitUrlLength-2 >= 0) {
a[splitUrlLength-2] = countryCode;
}
for (var i=splitUrlLength-3; i >= 0; i--) {
a[i] = splitUrl[i];
}
This makes the loop much more efficient, as it doesn't have to test the conditions on each iteration any more.
However, you don't need that loop to copy the strings into a new array at all. You are not using the original splitUrl
array for anything else, so you could just as well just mutate that:
function replacementCountryLanguageCode(url, countryCode, languageCode) {
const splitUrl = url.split("/");
const splitUrlLength = splitUrl.length;
if (splitUrlLength-1 >= 0) {
splitUrl[splitUrlLength-1] = languageCode;
}
if (splitUrlLength-2 >= 0) {
splitUrl[splitUrlLength-2] = countryCode;
}
return splitUrl.join("/");
}
Now, if you can ensure that the splitUrlLength
is always larger than 2, so you can always assign those last elements, you can simplify much more. Not just by omitting the if
statements, but completely by using a chain of slice
and concat
:
function replacementCountryLanguageCode(url, countryCode, languageCode) {
return url.split("/").slice(0, -2).concat([countryCode, languageCode]).join("/");
}
Upvotes: 2
Reputation: 192317
You don't need to loop the items, since you add them to exact indexes. Just slice after splitting using .slice(0, -2)
(all items but the last two), spread, and add the codes:
const url1 = "factory/news/fr/fr";
const url2 = "/factory/news/uk/en";
const url3 = "/region/factory/news/in/hi";
const replacementCountryLanguageCode = (url, countryCode, languageCode) => [
...url.split('/').slice(0, -2),
languageCode,
countryCode,
].join('/');
console.log(replacementCountryLanguageCode(url1, 'au', 'en'));
// Should return "factory/news/au/en"
console.log(replacementCountryLanguageCode(url2, 'fr', 'fr'));
// Should return "/factory/news/fr/fr"
console.log(replacementCountryLanguageCode(url3, 'es', 'es'));
// Should return "/region/factory/news/es/es"
Upvotes: 2
Reputation: 8321
You can implement it with splice
method which allows deletion and addition of elements at same time.
Please find working example below:
var url1 = "factory/news/fr/fr";
var url2 = "/factory/news/uk/en";
var url3 = "/region/factory/news/in/hi";
const replacementCountryLanguageCode = (url, countryCode, languageCode) => {
const arr = url.split("/")
arr.splice(arr.length-2, 2, countryCode, languageCode);
const finalUrl = arr.join("/");
return finalUrl;
}
console.log( replacementCountryLanguageCode(url1, 'au', 'en') );
// Should return "factory/news/au/en"
console.log( replacementCountryLanguageCode(url2, 'fr', 'fr') );
// Should return "/factory/news/fr/fr"
console.log( replacementCountryLanguageCode(url3, 'es', 'es') );
// Should return "/region/factory/news/es/es"
Upvotes: 1
Reputation: 122087
You could use rest parameter ...
here with reduceRight
method to create a function that can take any number of parameters and replace them in your url from the right to left.
var url1 = "factory/news/fr/fr";
var url2 = "/factory/news/uk/en";
var url3 = "/region/factory/news/in/hi";
const replacementCountryLanguageCode = (string, ...params) => {
return string.split('/').reduceRight((r, e) => {
let str = params.pop()
r.unshift(str ? str : e)
return r
}, []).join('/')
}
console.log( replacementCountryLanguageCode(url1, 'au', 'en') );
console.log( replacementCountryLanguageCode(url2, 'foo', '', 'fr') );
console.log( replacementCountryLanguageCode(url3, 'baz', 'es', 'es') );
Upvotes: 0
Reputation: 5708
You can take the last two item assignments outside of the for loop which will simplify and speed up your code. Although, the speed increase is probably negligible unless you are working with a huge number of elements.
var url1 = "factory/news/fr/fr";
var url2 = "/factory/news/uk/en";
var url3 = "/region/factory/news/in/hi";
const replacementCountryLanguageCode = (url, countryCode, languageCode) => {
const splitUrl = url.split("/");
const splitUrlLength = splitUrl.length;
let a = [];
a[splitUrlLength-1] = languageCode;
a[splitUrlLength-2] = countryCode;
for(let i = 0; i < splitUrlLength-2; i++) {
a[i] = splitUrl[i];
}
return a.join("/");
}
console.log( replacementCountryLanguageCode(url1, 'au', 'en') );
console.log( replacementCountryLanguageCode(url2, 'fr', 'fr') );
console.log( replacementCountryLanguageCode(url3, 'es', 'es') );
Upvotes: 0