Array.find Javascript

0

I have a question, this problem I could solve with a simple for but, well, I can not sleep with the doubts.

Using the Array.find() is supposed to work by taking the first found result of what was requested, I wanted to use it to find a file string that comes in two formats; to move it from one folder to another.

let archivos = ['prueba1','prueba2','prueba4','prueba5'];
let carpeta = fs.readdirSync(__dirname + '/archivos');
archivos.forEach(function(element) {

  carpeta.find(function(param) {
    let file = param.split(".");
    console.log(file[0])
      if (file[0] === element) {
        fs.renameSync(__dirname + '/archivos/' + file[0] + '.txt', __dirname + '/movidos/' + file[0] + '.txt')
        fs.renameSync(__dirname + '/archivos/' + file[0] + '.rar', __dirname + '/movidos/' + file[0] + '.rar')
      }
  })
})

Something simple like this, but when running it works only once and asks again for the same file and that's when it does not work anymore, I do not understand why it is encicla inside the find.

If someone knows the behavior of this function thoroughly, I would appreciate it:)

    
asked by GuestDeveloper 11.11.2018 в 06:13
source

1 answer

0

The find function iterates over the contents of an array by evaluating a function for each element. It will return the first element for which the function was evaluated as "true" ( truthy ) that is, the Boolean true , a non-zero number, a non-empty string, etc.

let numeros = [1,2,3,4,5];

function igualATres(num) {
  return num === 3;
};

let encontrado = numeros.find((num)=>{
  return igualATres(num);
});

The above causes each element of the array to be traversed. If at some point in the loop something truthy is returned then the iteration is short circuited: a candidate has already been found, that is the result of find .

If at any time a truthy is returned, the function continues to traverse the entire array and when it is finished it says that the result is undefined .

In your case, you are not using find for your purpose but you are using its side effect as a generic iterator, just as you would with a foreach, and this is because you are not returning executing an action given the condition.

Then the flow occurs:

  • I have ['file1.rar', 'file1.txt'] and others in my folder. It is an array of strings and does not change according to changes in the files after filling the array.
  • I look for files that start with archivo1
  • archivo1.rar meets the condition
  • Rename archivo1.rar and archivo1.txt moving them from folder
  • In the next iteration, carpeta still contains archivo1.txt
  • archivo1.txt meets the condition
  • I try to rename archivo1.rar and archivo1.txt by moving them from folder
  • As I already moved them, an error occurs, the files are no longer there.

A loop that would work instead would be to occupy find for its specific humble purpose. No logic, just return true or false.

archivos.forEach(function (element) {

    let encontrado = carpeta.find(function (param) {
        let file = param.split(".");
        return file[0] === element; // <-- corto circuito
    });
    if (encontrado) {
        console.log('Archivo encontrado es ${encontrado}');
        let file = encontrado.split(".");
        fs.renameSync(__dirname + '/archivos/' + file[0] + '.txt', __dirname + '/movidos/' + file[0] + '.txt');
        fs.renameSync(__dirname + '/archivos/' + file[0] + '.rar', __dirname + '/movidos/' + file[0] + '.rar');
    }
});

There are eight files in your folder. For each of the four conditions there are two files that satisfy it. Thanks to the short circuit you only get the first occurrence. Iteras about four conditions, you get four candidates, you rename two files for each candidate.

    
answered by 11.11.2018 в 11:40