3

Thanks for taking your time to read my question.

I need to remove all alphabetical characters and leading zeros from string elements in an array. The array will look something like this:

["DE73456","DE71238","FR00034","FR00036","ES00038","US00039","DE00098", ...]

The result should be the following array of integers:

[73456,71238,34,36,38,39,98, ...]

Eventually, I would like to determine the lowest omitted value from this ascending sorted list of numbers. I alreay found a JS function that would do the job by passing an integer array - and it works perfectly as desired.

Maybe we can somehow integrate the above mentioned requirement with the JS function below to determine the lowest omitted value.

var k = [73456,71238,34,36,38,39,98];

k.sort(function(a, b) { return a-b; });   // To sort by numeric

var offset = k[0];
var lowest = -1;
for (i = 0;  i < k.length;  ++i) {
  if (k[i] != offset) {
    lowest = offset;
    break;
  }
  ++offset;
}
if (lowest == -1) {
    lowest = k[k.length - 1] + 1;
}
return lowest;

So, in a nutshell, I would like to determine the lowest omitted value from an array of strings.

["DE73456","DE71238","FR00034","FR00036","ES00038","US00039","DE00098", ...]

Consequently, the result of the JS function should return 35 for the example stated above.

Thank you very much for your suggestions! I am looking forward to reading your comments.

nairolf
  • 33
  • 5
  • maybe helpful https://stackoverflow.com/questions/7753976/regular-expression-for-numbers-without-leading-zeros – Raghav Garg Oct 23 '20 at 18:57
  • If you remove all characters from a string, the string will be empty. I think you meant "alphabetical characters"? – JoelFan Oct 23 '20 at 18:58
  • 1
    You are right @JoelFan, the qustion was not very well stated in this regard. I´ve edited the question - thanks for pointing this out! – nairolf Oct 23 '20 at 19:04

4 Answers4

3

You can use this simple regex replacement:

repl = str.replace(/^[a-zA-Z]+0*/, "")

RegEx Demo

RegEx Details:

  • ^: Start
  • [a-zA-Z]+: Match an alphabet
  • 0*: Match zero or more 0s
  • Replacement is just an empty string
anubhava
  • 761,203
  • 64
  • 569
  • 643
3

You could also use a single character class ^[A-Z0]+ to match 1 or more occurrences of A-Z or a 0 from the start of the string ^ and then use array map.

s = s.replace(/^[A-Z0]+/, "")

const a = ["DE73456", "DE71238", "FR00034", "FR00036", "ES00038", "US00039", "DE00098"];
console.log(a.map(s => s.replace(/^[A-Z0]+/, "")))
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • 2
    Thank you very much! The merged code actually did the job. `const a = ["DE73456", "DE71238", "FR00034", "FR00036", "ES00038", "US00039", "DE00098"]; console.log(a.map(s => s.replace(/^[A-Z0]+/, ""))) var k = a.map(s => s.replace(/^[A-Z0]+/, "")); k.sort(function(a, b) { return a-b; }); // To sort by numeric var offset = k[0]; var lowest = -1; for (i = 0; i < k.length; ++i) { if (k[i] != offset) { lowest = offset; break; } ++offset; } if (lowest == -1) { lowest = k[k.length - 1] + 1; } console.log("Lowest = " + lowest);` – nairolf Oct 23 '20 at 20:20
2

You can also use match instead of removing the unwanted characters.

str = "FR00034"
str.match(/[1-9][0-9]*/)

RegEx Details:

  • [1-9]: the first character should be non zero number
  • [0-9]*: all the following numbers

The final function to get the lowest of all should look something like this.

function getLowestOf() {
    const numbers = arr.map((item) => Number(item.match(/[1-9][0-9]*/)[0]));
    const sorted = numbers.sort((a, b) => a - b);
    // console.log(sorted);
    return sorted[0];
}
const arr = ["DE73456","DE71238","FR00034","FR00036","ES00038","US00039","DE00098"];
console.log(getLowestOf(arr))
Raghav Garg
  • 3,601
  • 2
  • 23
  • 32
1

For the provided list sample a regular expression like ... (/^[0\D]+/) ... already is sufficient enough in order to be used for string replacement. Since this task, and also the additional task of casting a string into a number value, has to be processed for every array item, one wants to use Array.prototype.map.

In order to achieve the final result wished by the OP, one has to implement a function which gets the lowest omitted value from an unordered list of integers ...

const sampleList = ["DE73456","DE71238","FR00034","FR00036","ES00038","US00039","DE00098"];

// for the above samples a regex like ... /^[0\D]+/ ... already
// is sufficient enough ... [https://regex101.com/r/ZSDGvC/1/]

// an unsorted list of integers ...
console.log(
  sampleList
    .map(sample => Number(sample.replace((/^[0\D]+/), '')))
);


function getLowestOmittedValueFromIntegerList(list) {
  let lowestOmittedInteger;
  let hasOmittedValue = false;

  const maximumListCount = (list.length - 1);

  // use shallow copy for not mutating the original
  // ... and sort this new array in ascending order.
  list = Array.from(list).sort((a, b) => (a - b));

  // look for omitted value, save it and exit early.
  list.some((integer, idx) => {

    if (idx < maximumListCount) {
      if ((integer + 1) < list[idx + 1]) {

        lowestOmittedInteger = (integer + 1);
        hasOmittedValue = true;
      }
    }
    return hasOmittedValue;
  });

  return lowestOmittedInteger;
}

// the lowest omitted value from an unsorted list of integers ...
console.log(
  getLowestOmittedValueFromIntegerList(
    sampleList
      .map(sample => Number(sample.replace((/^[0\D]+/), '')))
  )
);

// proof of concept ...
console.log('\nproof of concept ...\n\n');

console.log( // expect the undefined value
  getLowestOmittedValueFromIntegerList([9,8,7,6,6,6,5,4,3,2,1,0])
);
console.log( // expect 7 
  getLowestOmittedValueFromIntegerList([9,8,6,6,6,5,4,3,2,1,0])
);

console.log( // expect 11
  getLowestOmittedValueFromIntegerList([0,1,2,3,4,5,6,7,8,9,10,12])
);
console.log( // expect the undefined value
  getLowestOmittedValueFromIntegerList([0,1,2,3,4,5,6,7,8,9,10,11,12])
);

console.log( // expect -1
  getLowestOmittedValueFromIntegerList([-4,-3,-2,0,1,2,3,4])
);
console.log( // expect -2
  getLowestOmittedValueFromIntegerList([-4,-3,-1,0,1,2,3,4])
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
  • Thanks Peter. However, I am looking for the lowest **unused** number within the range of the resulting array of integers. Thanks for helping out. – nairolf Oct 23 '20 at 19:40
  • @nairolf ... Which for the provided example would be?.. It is not quite clear from your explanation. Would it be `36` because this number sequence does not appear in all the other extracted numbers? – Peter Seliger Oct 23 '20 at 19:46
  • It would be 35. If you look at this part of the string array, 35 would be the lowest unused number within the range of the resulting integer array. `["FR00034","FR00036","ES00038","US00039"]` – nairolf Oct 23 '20 at 19:52
  • Which is ... *"get the lowest omitted value from an ascending sorted list of numbers*" ... a range is something different ... anyhow I'm already working on it ... – Peter Seliger Oct 23 '20 at 20:00
  • thanks for the clarification and your assistance. Much appreciated! – nairolf Oct 23 '20 at 20:03
  • Sorry, my bad. I am new to this platform, it was late already, and it seems like I up voted the wrong suggestion. I´ve corrected it. Thank you very much again for your assistance! – nairolf Oct 25 '20 at 14:41