Ich musste kürzlich einen Test für ein Vorstellungsgespräch durchführen, und die Eingabeaufforderung bestand darin, eine Funktion zu codieren, die bei einer Reihe von negativen und positiven Zahlen die Zahl 0 am nächsten zurückgibt.

Meine Funktion funktioniert korrekt, aber ich habe vom Personalvermittler gehört, dass meine Funktion nicht sehr leistungsfähig ist und dass die Lesbarkeit nicht besonders gut ist. Hier ist das Problem, das sie erwähnt haben:

  • Performances à Double Check (Filter + Sortieren + für + Push + Reserve + Shift, 4 identische Aufrufe an Math.abs)
  • Mangelnde Lesbarkeit (4 if / else if)

Ich möchte wissen, wie ich meine Funktion hätte verbessern können, um sie leistungsfähiger und lesbarer zu machen.

Hier ist meine Funktion:

const closestToZero = (arr) => {
  // 1-a variables:
  let positiveNumbers = [];
  let negativeNumbers = [];

  // 1-b returns 0 if the input is either undefined or an empty array
  if(typeof(arr) === 'undefined' || arr.length === 0) {
    return 0
  }

  // 2- filter out non-number values then sort the array
  const onlyNumbers = arr.filter(item => typeof(item) === 'number').sort((a,b) => a-b);

  // 3- split the numbers into positive numbers and negative numbers
  for(let i = 0; i < onlyNumbers.length; i++) {
    if(onlyNumbers[i] > 0) {
      positiveNumbers.push(onlyNumbers[i])
    } else if (onlyNumbers[i] < 0) {
      negativeNumbers.push(onlyNumbers[i])
    }
  }

  // 4- reverse the negative array to get the closest to 0 at the first index
  let reversedNegativeArray = negativeNumbers.reverse()

  // 5- get rid of all the other values and keep only the closest to 0, if array empty return 0
  let closestPositiveNumber = positiveNumbers.length > 0 ? positiveNumbers.shift() : 0
  let closestNegativeNumber = reversedNegativeArray.length > 0 ? reversedNegativeArray.shift() : 0

  // 6- Compare the result of the substraction of the closestPositiveNumber and the closestNegativeNumber to find the closestToZero
  if(closestPositiveNumber - Math.abs(closestNegativeNumber) > 0 && closestNegativeNumber === 0 ) {
    return closestPositiveNumber
  } else if (closestPositiveNumber - Math.abs(closestNegativeNumber) < 0 && closestPositiveNumber === 0) {
    return closestNegativeNumber
  } else if(closestPositiveNumber - Math.abs(closestNegativeNumber) > 0) {
    return closestNegativeNumber
  } else if (closestPositiveNumber - Math.abs(closestNegativeNumber) <= 0) {
    return closestPositiveNumber
  }
}

Anforderungen:

  • Wenn die nächste eingegebene Zahl entweder negativ oder positiv sein könnte, gibt die Funktion die positive zurück
  • Wenn das Eingabearray undefiniert oder leer ist, gibt die Funktion 0 zurück

Wenn die Eingabe [8, 5, 10] ist, gibt die Funktion 5 zurück

Wenn die Eingabe [5, 4, -9, 6, -10, -1, 8] ist, gibt die Funktion -1 zurück

Wenn die Eingabe [8, 2, 3, -2] ist, geben die Funktionen 2 zurück

-1
AziCode 7 Feb. 2020 im 19:36

3 Antworten

Beste Antwort

Ihre Funktion ist in der Tat sehr kompliziert. Sie können die Funktion Math.abs hier gut nutzen, um einiges aufzuräumen. Hier ist eine js-Implementierung, die ich gegeben hätte

test = [-1, 5, 4, -9, 6, -10, -1, 8, 1]; 


function closeToZero(arr){

    if(typeof(arr) === 'undefined' || arr.length === 0) {
        return 0;
    }

    ret = test[0]; 

    for(i = 1; i < test.length; i++){
        if(Math.abs(ret) >= Math.abs(test[i]) ){
            if(Math.abs(ret) == Math.abs(test[i])){
               ret = Math.max(ret, test[i]);
            }else{
                ret = test[i];
            }
        }
    }
    return ret; 

}

print(closeToZero(test));

Optional können Sie auch nach fehlerhaften Eingaben suchen, wenn dies erforderlich war

0
Mitchel Paulin 7 Feb. 2020 im 17:24

Es besteht die Möglichkeit, dass der Personalvermittler eine Lösung gefunden hat, die reduce ebenfalls unlesbar verwendet.

Aber um Andreas Kommentar zu erweitern.

Hier ist ein Beispiel-Snippet mit einer Funktion, die Reduzieren verwendet und die absoluten Werte oder das Vorzeichen vergleicht.

const closestToZero = (arr) => {
    if(!arr || arr.length === 0) return 0;
    return arr.reduce((acc, x) =>  (Math.abs(x) < Math.abs(acc) || (Math.abs(x) === Math.abs(acc) && x > acc)) ? x : acc);
}

console.log(closestToZero());
console.log(closestToZero([]));
console.log(closestToZero([8,5,10]));
console.log(closestToZero([5, 4, -9, 6, -10, -1, 8]));
console.log(closestToZero([8, -2, 3, 2]));
0
LukStorms 7 Feb. 2020 im 18:26

Obwohl dies nicht das beste StackExchange-Forum für eine "Antwort" ist, gibt Andreas tatsächlich eine. Eine Lösung könnte folgendermaßen aussehen: (Pseudocode)

winner = 0      # arbitrarily assume the zeroth element is closest
for (i from 1 to array-length):
   if abs(array[i]) < abs(array[winner]):    # this one's closer ...
      winner = i

Die Funktion abs() (absoluter Wert) ist natürlich ein Indikator dafür, "wie nahe die Zahl an Null liegt". abs(-3) == 3 und so weiter.

0
Mike Robinson 7 Feb. 2020 im 16:52