1

Imagine I have the following array of objects:

 const object = [
  {Name: "A", Nr: "01"},
  {Name: "B", Nr: "02"},
  {Name: "C", Nr: "04"},
  {Name: "D", Nr: "06"},
  {Name: "E", Nr: "07"},
 ];

And I have the following function:

const findCurrentNumber = (obj) => {
    let numbers = obj.map((a) => {
      return parseInt(a["Nr"]);
    });

    numbers.sort((a, b) => a - b);
    let current = numbers[numbers.length - 1];
    for (let i = numbers.length - 1; i > 0; i--) {
      if (numbers[i - 1] !== numbers[i] - 1) current = numbers[i - 1];
    }

    return current + 1;
  };

I will get the value 3 as return. But I want to do the same just using array methods (map, sort, reduce etc). I was trying and I stopped here:

const obj = object.map(a => parseInt(a["Nr"])).sort((a, b) => a - b);

I don't know how to continue from the part I declared the current variable.

Is it possible? If so, how can I do it?

Thank you!

Lit2000hania
  • 97
  • 11
  • 1
    What exactly is the purpose of the last for loop? – Taplar Nov 12 '20 at 15:13
  • 1
    It looks like the for loop is just grabbing the element at [0] and adding 1 to it. Not sure why you need a loop to do that – Taplar Nov 12 '20 at 15:15
  • @Taplar it *might* be the first element or not. It's the last element (in regards to the loop, it's going as close as possible to the beginning of the array) that is *not* `1` larger than the element following it. – VLAZ Nov 12 '20 at 15:17
  • @Taplar I edited the question, I guess you can have a better understanding now – Lit2000hania Nov 12 '20 at 15:17
  • @Polalas actually, it's even less clear. You don't even have numbers, you're not *adding* one to `current`, you're doing *string concatenation*. I'm still not sure what the point is. – VLAZ Nov 12 '20 at 15:18
  • @Taplar for `[1, 2, 4]` it's going to end up with `current = 2` (index `1`) – VLAZ Nov 12 '20 at 15:19
  • @VLAZ I'm not doing string concatenation as I'm converting to int before. – Lit2000hania Nov 12 '20 at 15:20
  • Ah, sorry. Still, what is the idea? Find the first gap in the numbering? – VLAZ Nov 12 '20 at 15:20
  • @VLAZ that is right! Find the first gap – Lit2000hania Nov 12 '20 at 15:21
  • Nvm, I missed that part of the if is doing `[i] - 1`. @VLAZ yeah I plugged it into a fiddle and saw I misread the logic. – Taplar Nov 12 '20 at 15:22
  • @Taplar https://jsbin.com/zixoyegohe/edit?js,console – VLAZ Nov 12 '20 at 15:23
  • If you want to find the first gap that would be something like, `object.map(a => parseInt(a["Nr"])).sort((a, b) => a - b).find((elem, index, arr) => index < arr.length - 1 && elem != arr[index + 1]);` – Taplar Nov 12 '20 at 15:29
  • @Taplar this doesn't work! Look at this example: https://jsbin.com/womivek/edit?js,console where the return should be 4 and not 1 – Lit2000hania Nov 12 '20 at 15:40
  • @Polalas typo on my part. `elem != arr[index + 1]` should be `elem + 1 != arr[index + 1]`. It returns 4 correctly then – Taplar Nov 12 '20 at 17:19

1 Answers1

1

You could take an approach for How to write the code with less time complexity for finding the missing element in given array range? and take the numerical values of Nr.

function getMissing(array) {
    var min = array[0],
        max = array[0],
        missing = new Set;
    
    array.forEach(v => {
        if (missing.delete(v)) return;                   // if value found for delete return
        if (v < min) while (v < --min) missing.add(min); // add missing min values
        if (v > max) while (v > ++max) missing.add(max); // add missing max values
    });
    return missing.values().next().value;                // take the first missing value
}

const
    data = [{ Name: "A", Nr: "01" }, { Name: "B", Nr: "02" }, { Name: "C", Nr: "04" }, { Name: "D", Nr: "06" }, { Name: "E", Nr: "07" }],
    first = getMissing(data.map(({ Nr }) => +Nr));

console.log(first);

Classic approach. By checking an ordered array of numbers and get the one where the next value has a delta of more than one. Finally add one for the missing number.

const
    data = [{ Name: "A", Nr: "01" }, { Name: "B", Nr: "02" }, { Name: "C", Nr: "04" }, { Name: "D", Nr: "06" }, { Name: "E", Nr: "07" }],
    first = 1 + data
        .map(({ Nr }) => +Nr)
        .sort((a, b) => a - b)
        .find((l, i, { [i + 1]: r = Number.MAX_VALUE }) => r >= l + 2);

console.log(first);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Thank you, Nina! I appreciate you showing me this method with less time complexity. I will not set your response as the questions' answer because that is not specifically what I wanted, but I really appreciate! Danke – Lit2000hania Nov 12 '20 at 15:47
  • [I commented on the original](https://stackoverflow.com/questions/50942303/how-to-write-the-code-with-less-time-complexity-for-finding-the-missing-element/50942576#comment114582634_50942576) but I'd like to bring attention to the same thing here. This first algorithm is actually `O(n*m)` where `n` is the input size and `m` is the largest gap between the numbers. For example `[1, 3]` will only generate `2` but `[0, 9001]` will generate the entire range from `1` to `9000` because of the gap between the two elements. – VLAZ Nov 12 '20 at 16:10
  • @NinaScholz in this example https://jsbin.com/velobip/edit?js,console it doesn't return the exact value it was expect to return, which is 2 – Lit2000hania Nov 12 '20 at 16:31
  • @Polalas, thank you for the hint. i changed the items, now it checks the next value or a max value. – Nina Scholz Nov 12 '20 at 16:51