skip to Main Content

I need to perform an action in JavaScript code only if no array elements fulfill a condition. What’s the optimal way to do it?

In this particular case, I need to push something to the dataLayer only if it’s not already present. Here’s what I did:

if (!window.dataLayer.some(
     (element) => element.event === 'some_label',
   )) {
    gtm.push(someTrackingObject);
   }

Is there a better / more concise way?

3

Answers


  1. You can use .every()

    If you want to check if no elements fulfull one specific condition, just inverse the condition

    datalayer.every((element) => element.event !== "some_label")
    
    > true // if no elements has "some_label"
    > false // if some element has "some_label"
    

    Using .some() is good enough, so .every() is just an alternative way.

    Login or Signup to reply.
  2. Your current approach using Array.prototype.some() is optimal for checking if no array elements fulfill a condition, as it stops iterating over the array as soon as the condition is met, avoiding unnecessary iterations.

    if (!window.dataLayer.some((element) => element.event === 'some_label')) {
        gtm.push(someTrackingObject);
    }
    

    However, if you want a more concise version, you can use the Array.prototype.indexOf() method to achieve the same result:

    if (window.dataLayer.indexOf(someTrackingObject) === -1) {
        gtm.push(someTrackingObject);
    }
    

    Here, Array.prototype.indexOf() returns the first index at which a given element can be found in the array, or -1 if it is not present. Note that this approach assumes that someTrackingObject is unique in the window.dataLayer array.

    Both approaches have their pros and cons:

    • Array.prototype.some():
      • Pros:
        • Stops iterating over the array as soon as the condition is met, making it more efficient in cases where the element is found early in the array.
      • Cons:
        • Less concise than Array.prototype.indexOf()
    • Array.prototype.indexOf():
      • Pros:
        • More concise than Array.prototype.some().
      • Cons:
        • Does not stop iterating over the array, which may be less efficient if the element is found late in the array.

    In summary, your current approach using Array.prototype.some() is optimal for checking if no array elements fulfill a condition, and you can consider using Array.prototype.indexOf() for a more concise version if someTrackingObject is unique in the window.dataLayer array.

    Login or Signup to reply.
  3. What you did already is a good way to do it. You can also use .every() and check for !== 'some_label'.

    If you have a lot of data you can use a map or set to be more efficient when it comes to lookup time. But this only makes sense when you have multiple lookups and a large array size.

    // build set with set and events
    const set = window.dataLayer.reduce((acc, el) => {
        acc.add(el.event);
        return acc;
    }, new Set())
    
    
    // check if the set includes the label
    if (!set.includes('some_label')) {
        gtm.push(someTrackingObject);
    }
    

    Update

    Search for the element. .find exits on the first match so you don’t have to check every element in the array.

    // check if the set includes the label
    if (window.dataLayer.find(el => el.event === 'some_label') === undefined) {
        gtm.push(someTrackingObject);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search