If you want loops to run concurrently you can't use for loops and you do not want to use delay(). The several things tutorial at a time shows how to have many things happening, each at their own time.
As you have guessed you can't, at least not that simply. You have to break up the loop into lots of little bits and don't use delay. This is called implementing a state machine.
This is an example of the FastLed example patterns implemented as a state machine. Study them and comparer them to the original example code.
// Multiple patterns in a state machine format
// using the FastLED library
// by Mike Cook 2017
#include "FastLED.h"
// first set up the parameters to use in the pattern calling
unsigned long patternInterval [] = { 500, 40, 20, 200, 5 }; // how often each pattern updates
unsigned long lastUpdate [5] ; // for millis() when last update occurred
boolean patternEnabled [] = {true,true,false,true,true}; // should the pattern be called at all
byte patternState[5]; // state machine variable for patterns - this initialises them to zero
// now set up the LEDs to use
#define NUM_LEDS 64
#define DATA_PIN 3
#define CLOCK_PIN 13
CRGB leds[NUM_LEDS];
// Constants for patterns
// for Fire2012
#define COOLING 20
#define SPARKING 50
#define COLOR_ORDER BGR
// now set up the array of pointers to each pattern
void (*patternPtrs[5])(int index,byte state); //the array of pattern pointers
void setup() {
//initialises the array of pattern pointers
patternPtrs[0] = blinkOne;
patternPtrs[1] = cylon;
patternPtrs[2] = fire;
patternPtrs[3] = colorWipe;
patternPtrs[4] = rainbowCycle;
//initialises the FastLED driver you want
//FastLED.addLeds<APA102,leds, NUM_LEDS); // 13 clock and 11 data
FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(leds, NUM_LEDS); // 13 clock and 11 data
FastLED.setBrightness(8);
}
void loop() {
for(int i = 0; i<5; i++) { // go through all the patterns and see if it is time to call one
if(patternEnabled[i] && millis() - lastUpdate[i] > patternInterval[i]){
lastUpdate[i] = millis();
callPatterns(i, patternState[i]);
}
}
}
void callPatterns(int index, byte state) {
(*patternPtrs[index])(index,state); //calls the pattern at the index of `index` in the array
}
// These are the pattern functions written as a state machine
// this is the Blink program in FastLED's example folder
void blinkOne(int index,byte state) {
if(state == 0){
leds[3] = CRGB::Blue;
FastLED.show();
patternState[index] = 1; // move on the state machine for the next call
}
if(state == 1){
leds[3] = CRGB::Black;
FastLED.show();
patternState[index] = 0;
}
}
// this is the Cylon program in FastLED's example folder
// we will use LEDs 8 to 15 to show this
void cylon(int index,byte state) {
static int i = 8; // replaces the loop index
if(state == 0){
leds[i] = CRGB::Red;
FastLED.show();
patternState[index] = 1; // move on the state machine for the next call
}
if(state == 1){
// now that we've shown the leds, reset the i'th led to black
leds[i] = CRGB::Black;
i++; // increment what was the loop variable
if(i >= 16){ // we have finished one direction
patternState[index] = 2;
i--;
}
else {
patternState[index] = 0;
}
}
// Now go in the other direction only green
if(state == 2){
leds[i] = CRGB::Green;
FastLED.show();
patternState[index] = 3; // move on the state machine for the next call
}
if(state == 3){
// now that we've shown the leds, reset the i'th led to black
leds[i] = CRGB::Black;
i--; // decrement what was the loop variable
if(i < 8){ // we have finished the return, go back to the start
patternState[index] = 0;
i= 8; // ready to start again
}
else {
patternState[index] = 2;
}
// note that this could be better implemented but it has been written like this to keep it close to the original example
// so you can see what changes have been made
}
}
// this is the Fire2012 program in FastLED's example folder
void fire(int index,byte state) {
// using LEDs 16 to 32
// Array of temperature readings at each simulation cell
const byte startLED = 16; // first LED in section
const byte numLEDs = 16;
static byte heat[numLEDs];
random16_add_entropy( random());
// Step 1. Cool down every cell a little
for( int i = 0; i < numLEDs; i++) {
heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for( int k= numLEDs - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
}
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
if( random8() < SPARKING ) {
int y = random8(7);
heat[y] = qadd8( heat[y], random8(160,255) );
}
// Step 4. Map from heat cells to LED colors
for( int j = 0; j < numLEDs; j++) {
leds[j+startLED] = HeatColor( heat[j]); // transfer heat array to LEDs
}
FastLED.show(); // display this frame
}
//colorWipe modified from Adafruit example to make it a state machine
// uses LEDs 32 to 40
void colorWipe(int index,byte state) {
static int i =0; // used as state variable
static byte firstLED = 32;
static byte numLEDs = 8;
leds[i+firstLED] = CRGB::Yellow;
FastLED.show();
i++;
if(i >= numLEDs){
i = 0;
for(int j;j<numLEDs; j++) leds[j+firstLED] = CRGB::Black; // blank out strip
}
}
// rainbowCycle modified from Adafruit example to make it a state machine
// uses LEDs 48 to 64
void rainbowCycle(int index,byte state) {
static uint16_t j=0; // used as state variable
static byte firstLED = 48;
static byte numLEDs = 16;
for(int i=0; i< numLEDs; i++) {
leds[i+firstLED].setHSV( (((i * 256 / numLEDs) + j) & 255), 255, 255);
}
FastLED.show();
j++;
if(j >= 256*5) j=0;
}