Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you return different values each time you invoke a function? - JavaScript

I have a function below, thats objective is to look in a local directory with images and auto post it to twitter. I do not want the pictures to re-upload if they have been uploaded before.

   function random_from_array(images){
     return images[Math.floor(Math.random() * images.length)];
   }

The function that is utilizing the random_from_array function.

function upload_random_image(images){
  console.log('Opening an image...');
  var image_path = path.join(__dirname, '/images/' + random_from_array(images)),
      b64content = fs.readFileSync(image_path, { encoding: 'base64' });

  console.log('Uploading an image...');

  T.post('media/upload', { media_data: b64content }, function (err, data, response) {
    if (err){
      console.log('ERROR:');
      console.log(err);
    }
    else{
      console.log('Image uploaded!');
      console.log('Now tweeting it...');

      T.post('statuses/update', {
        media_ids: new Array(data.media_id_string)
      },
        function(err, data, response) {
          if (err){
            console.log('ERROR:');
            console.log(err);
          }
          else{
            console.log('Posted an image!');
          }
        }
      );
    }
  });
}

As of right now it is just picking a random number from the array parameter that is passed in, however I was wondering if there is any way that every time it's invoked it can return in such a fashion below. Whenever I try to loop and return each iteration it only gives me the first iteration, assumingely cause the return ceases it.

   return images[0]  
   return images[1] //Next Invocation
   return images[2] //Next Invocation...

I'm following this tutorial https://botwiki.org/resource/tutorial/random-image-tweet/#posting-images

Thank you in advance for any help, I'm stuck.

like image 825
Mr.Mikey Avatar asked Feb 17 '26 07:02

Mr.Mikey


1 Answers

If you can change the calling code's structure, consider using a higher-order function instead: call with the images array once, which returns a function that, when called, returns the next element in the array:

const makeIterFn = images => () => images.shift();

And then call it like:

const iterFn = makeIterFn(arrOfImages);
iterFn(); // first item in array
iterFn(); // second item in array

If you want to avoid mutating the argument, slice it first:

const makeIterFn = (images) => {
  const imagesCopy = images.slice();
  return () => imagesCopy.shift();
};

You could also use the built-in array iterator - instead of random_from_array, call the array's Symbol.iterator to get an iterator for it, and then call its next() method to get the next item in the array:

const iterator = arrOfImages[Symbol.iterator]();
iterator.next().value // first image
iterator.next().value // second image

If this is being done in a loop, it would probably make more sense to use for (const image of arrOfImages) { if possible, but there's not enough context to say for sure.

like image 184
CertainPerformance Avatar answered Feb 19 '26 21:02

CertainPerformance



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!