When processing collections of data, choose efficient algorithms and data structures that minimize computational complexity. Use appropriate array methods (filter, find, map, reduce) and consider batching operations when possible.

Key principles:

Example from the codebase:

// Efficient: Use find() for single item lookup
const localVariable = scopedVariables.find((v) => v.name === prefix);

// Efficient: Use Map for deduplication
const baseVariables = Array.from(new Map([...jitVariables, ...variables].map((item) => [item.name, item])).values());

// Efficient: Batch operations instead of individual updates
const bulkUpdatePreferences = (preferences: Preference[]) => async (channels: ChannelPreference) => {
  await novu.preferences.bulkUpdate(
    preferences.map((el) => {
      const channelsToUpdate = Object.keys(channels)
        .filter((channel) => oldChannels.includes(channel))
        .reduce((acc, channel) => {
          acc[channel] = channels[channel];
          return acc;
        }, {});
      return { preference: el, channels: channelsToUpdate };
    })
  );
};

This approach reduces time complexity and improves performance, especially when dealing with large datasets or frequent operations.