Nesh
Nesh

Reputation: 2561

Replacing the last two items from an array in JavaScript

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

Answers (5)

Bergi
Bergi

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

Ori Drori
Ori Drori

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

Jasdeep Singh
Jasdeep Singh

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"

Read about splice here

Upvotes: 1

Nenad Vracar
Nenad Vracar

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

Ivan86
Ivan86

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

Related Questions