1

I have a string and I need to remove the last word of a string if the last before word is a number and increment the number. If the last before word is not a number, we keep checking until the same word has occurred and throw the count along with the word. This is an extension of Count string occurrence and replace with string and count - JS - The latter part is working. Unable to get the first example working. Please advice.

Example:

  1. Model transfer 2 transfer - Model transfer 3 //Expected output
  2. Model transfer transfer Transfer - Model transfer 3 //Expected output
  3. Model transfertransfer Transfer Transfer - Model transfer 4 //Expected output
  4. Model transfer - Model transfer //Expected output
  5. Model - Model //Expected output

var name = "Model Transfer 2 transfer";
const name1 = 'Model transfer model transfer';
const name2 = 'Model transfer transfer transfer';
const name3 = 'Model Transfer transfer Transfer';
const name4 = 'Model transfer transfer transfer';
const renameNameOccurrence = (
  name,
  occurrenceName
) => {
  var regExp = new RegExp(`(?<=${occurrenceName}\\s)(.+?)(?=\\s+${occurrenceName})`, "ig");
  var results = Number(name.match(regExp)[0]);
  if (typeof results == 'number') {
    const abc = name.replace(/\w+[.!?]?$/, '');
  }
  const nameSplit = name.split(" ");
  const occurrenceCount = (
    name.match(new RegExp(`${occurrenceName}`, "gi")) || []
  ).length;
  let modifiedName = "";
  if (occurrenceCount > 1) {
    for (let i = 0; i < nameSplit.length - 1; i++) {
      if (nameSplit[i].toLowerCase() === nameSplit[i + 1].toLowerCase()) {
        if (occurrenceCount > 1) {
          modifiedName = name
            .replace(new RegExp(`\\s*${occurrenceName}\\s*`, "gi"), "")
            .concat(` ${occurrenceName.toLowerCase()} ${occurrenceCount}`);
        } else {
          modifiedName = name;
        }
      } else {
        modifiedName = name;
      }
    }
  } else {
    modifiedName = name;
  }

  return modifiedName;
};


console.log('name', renameNameOccurrence(name, 'transfer')); //Model Transfer 3
console.log('name1', renameNameOccurrence(name1, 'transfer')); //Model transfer model transfer
console.log('name2', renameNameOccurrence(name2, 'transfer')); //Model transfer 3
console.log('name3', renameNameOccurrence(name3, 'transfer')); //Model transfer 3
console.log('name4', renameNameOccurrence(name4, 'transfer')); //Model transfer 3
arunmmanoharan
  • 2,535
  • 2
  • 29
  • 60

1 Answers1

1

This solution relies on split by words and an iterative approach on counting instances of transfer. It also detects if an integer precedes the last word, and if so, handles that situation as described in code below:

var name = "Model Transfer 2 transfer";
const name1 = 'Model transfer model transfer';
const name2 = 'Model transfer transfer transfer';
const name3 = 'Model Transfer transfer Transfer';
const name4 = 'Model transfer transfer transfer';

const renameNameOccurrence = (name, occurrenceName) => {
    
    // split by words as lowercased
    let s = name.toLowerCase().split(" ")  
    
    // Now count the 'transfer' words
    let t = 0;
    for (var i = 0; i < s.length; i++) {
        
        if (s[i] == "transfer") {
            t++;
        }
    }
    
    // Now see if a integer precedes last word
    
    w = s.length - 2; // -2 since length is base 1, and we need word before last
    if (w > 1) {  // excluding the assumed 1st word Model
    
        if ( parseInt( s[w] ).toString() == s[w]) {
            t++; // increment transfer words, since count is consistent
            console.log("hello")
        }
    }
    
    // Now recompose the string
    
    
    
    if (t > 1) {
        
        return name.split(" ")[0] + " Transfer " + t
    
    }
    else if (t > 0) {
        return name.split(" ")[0] + " Transfer"
    }
    else {
        return name.split(" ")[0]
    }
    
    
}

/*

Model transfer 2 transfer - Model transfer 3 //Expected output
Model transfer transfer Transfer - Model transfer 3 //Expected output
Model transfertransfer Transfer Transfer - Model transfer 4 //Expected output
Model transfer - Model transfer //Expected output
Model - Model //Expected output

*/

console.log( renameNameOccurrence( "Model transfer 2 transfer" ))
console.log( renameNameOccurrence( "Model transfer transfer Transfer" ))
console.log( renameNameOccurrence( "Model transfer transfer Transfer Transfer" ))
console.log( renameNameOccurrence( "Model transfer" ))
console.log( renameNameOccurrence( "Model" ))
GetSet
  • 1,511
  • 2
  • 10
  • 13
  • can we not hardcode Model keyword in the function. This function should be reusable as to any string . – arunmmanoharan Sep 15 '20 at 01:09
  • You can always take that out. It doesn't have to return "Model". As to be reusable to any string, i dont know what you mean. I was going by your examples. – GetSet Sep 15 '20 at 01:11
  • Sorry. It can be Name transfer 2 transfer or even Something transfer transfer transfer. – arunmmanoharan Sep 15 '20 at 01:12
  • thanks man. That worked. I missed a Scenario. If the string doesnt have "transfer" followed by "transfer", we should return the original string. Eg: "Model transfer model transfer" should return "Model transfer model transfer" – arunmmanoharan Sep 15 '20 at 13:39
  • Yeah, that changes the algorithm a bit – GetSet Sep 15 '20 at 13:43
  • thanks man. The last word will always be transfer. But transfer can be case insensitive as well. – arunmmanoharan Sep 15 '20 at 13:43
  • See if you can tweak the code a bit to work with all your use cases. Because you can certainly return the original string early in that first loop if the word doesn't equal "transfer" AND is not an integer. ... Just start that first loop from index 1, so to skip the first word. – GetSet Sep 15 '20 at 13:50