0

I have an empty array (called zoomthumbsarray) which gets values pushed to it whilst a 'for' loop is running. This 'for' loop is checking if a thumbnail image is present in the backend against the particular product the user is viewing. If there is an image it gets added into a vertical slider. The current issue is there are non colour specific images (like lifestyle shots) that are being added into the slider multiple times.

So I need to check if the image found in the for loop is currently stored in the array. If it is present, the image has already been generated and I don't want it to get pulled into the slider again. If it hasn't then the image will get added.

Below is the code I am working on. I would presume indexOf would be used but can't get this to work.

Any help would be really appreciated.

var zoomthumbsarray = [] // Empty array which gets populated by .push below during loop

for (var i = 0; i < storeImgsArr.length; i++) { // storeImgsArr finds the quantity of attributes present against the product. This loops and increments counter if there is another attibute image
    for (var e = 0; e < storeImgsArr[i].images.imgL.length; e++) { // Loop and increment counter if there is a Large image 

        zoomthumbsarray.push(storeImgsArr[i].images.imgS[e].slice(-16)); // Slices off last 16 characters of image path i.e. _navy_xsmall.jpg or 46983_xsalt1.jpg and pushes this into 'zoomthumbsarray' array

        // if statement sits here to build the html to add the image to the slider

    }
}

zoomthumbsarray = [] // Resets array to zero

ANSWER As answered by Chris I used $.unique to only keep unique values in the array. Then wrap an if statement around the code to build the thumb image html if the array === 0 or if the current image isn't already in the array.

Updated code below:

var zoomthumbsarray = [] // Empty array which gets populated by .push below during loop

for (var i = 0; i < storeImgsArr.length; i++) { // storeImgsArr finds the quantity of attributes present against the product. This loops and increments counter if there is another attibute image

    if (zoomthumbsarray === 0 || zoomthumbsarray.indexOf(storeImgsArr[i].images.imgS[e].slice(-16)) < 0) { // If statement is true if array === 0 or if the current image isn't already in the array 

        for (var e = 0; e < storeImgsArr[i].images.imgL.length; e++) { // Loop and increment counter if there is a Large image 

            zoomthumbsarray.push(storeImgsArr[i].images.imgS[e].slice(-16)); // Slices off last 16 characters of image path i.e. _navy_xsmall.jpg or 46983_xsalt1.jpg and pushes this into 'zoomthumbsarray' array

            zoomthumbsarray = $.unique(zoomthumbsarray); //Keeps only unique elements

            // if statement sits here to build the html to add the image to the slider

        }
    }
}

zoomthumbsarray = [] // Resets array to zero

5
  • 1
    indexOf returns -1 if not found or an index, not true|false Commented Jan 16, 2014 at 17:09
  • @elclanrs Thanks I've actually edited the question and removed my attempt of indexOf as hacked about with it so much it's probably misleading. Question still stands at how I would achieve comparing value in array to value in for loop. Commented Jan 16, 2014 at 17:15
  • @Chris The $.unique worked perfectly! Thanks for that little gem. Just had to add a new if statement around the second for loop to incorporate this and job done! Thanks all for your comments Commented Jan 17, 2014 at 10:24
  • @Damodog glad to help! What's with zoomthumbsarray === 0? Commented Jan 17, 2014 at 22:09
  • @chris The array is empty on the first iteration of the code so I have this present just for this. Commented Jan 18, 2014 at 21:34

3 Answers 3

2

Some cheap and dirty ideas:

Using underscore/lodash:

zoomthumbsarray = _.uniq(zoomthumbsarray); //Keeps only unique elements

jQuery has one as well:

zoomthumbsarray = $.unique(zoomthumbsarray); //Keeps only unique elements

then you loop through the array and build HTML.

Update: There's something a bit odd about the rest of the JS. Might this work (if you're using a new enough browser)?

var zoomthumbsarray = [];
storeImgsArr
    .map(function(item) { return item.images.imgS; })
    .forEach(function(imgS) {
        zoomthumbsarray = zoomthumbsarray.concat(imgS.map(function(imagePath) {
            return imagePath.slice(-16);
        }));
    });
zoomthumbsarray = $.unique(zoomthumbsarray);
Sign up to request clarification or add additional context in comments.

7 Comments

(Nitpicker's note: If performance matters (and it shouldn't if you're just running this once per page), an object/keys model has the potential to be faster. It probably won't be, but it could be. JSPerf is the only way to settle these debates for sure.)
Instead of udnerscore maybe lodash ?
@skmasq sure, it would look exactly the same. I haven't heard of lodash before - thanks for pointing it out.
I think you misinterpreted me, loadsh in majority functions is faster than underscore. And in many features have more functionality available.
@Bergi at the end, to remove duplicates. Then you build the HTML all at once and reset zoomthumbsarray.
|
0

I have tried indexOf (see first if statement below) but this doesn't work.

As @elclanrs said, indexOf does return the index in the array not a boolean. You only will need to see if it's >= 0 to test whether an image is already contained in the array.

var zoomthumbsarray = [];
for (var i = 0; i < storeImgsArr.length; i++) {
    for (var e = 0; e < storeImgsArr[i].images.imgL.length; e++) {
        var image = storeImgsArr[i].images.imgS[e].slice(-16);

        if (zoomthumbsarray.indexOf(image) < 0) { // not yet in the array
            zoomthumbsarray.push();
            // and build the html to add the image to the slider
        }
    }
}

If you have really lots of images and notice this starts slowing the page down, then there are too many images in your page anyway. No, joke aside; …then check the optimisation by @Ivey.

Comments

0

instead of using an array you can use an object to store the images as keys and a dummy value (possibly true). then you can extract the keys from this object.

var images = {};

for (var i = 0; i < storeImgsArr.length; i++) { 
    for (var e = 0; e < storeImgsArr[i].images.imgL.length; e++) { 
        images[storeImgsArr[i].images.imgS[e].slice(-16))] = true; 
    }
}
var zoomthumbsarray = [];
for(var k in images) {
    zoomthumbsarray.push(k);
    // build the html to add the image to the slider
}

EDIT: Added build html comment

1 Comment

Please also suggest where to put the // statement to build the html, since this need a little modification compared to OP's structure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.