I like your strength/weakness observation. But if you are mutating index variables, you have a hard case, and it probably will be easier to express with a manual loop than trying to shoehorn it into awkward functional constructs.
An example is the "discard elements by a predicate" function, aka Vec::retain in Rust, std::remove in C++. Rust implements this using a for loop. Maybe it can be done with functional constructs, but it would be harder to write and to understand.