Extracting characters of two strings in a for loop

Without any packages:

\documentclass[]{article}
\makeatletter
\newcommand\printchar[2]{#1,#2}
\def\parsefoo#1#2,#3#4|{%
    \ifx\relax#1\relax%
    \else%
        \ifx\relax#3\relax%
        \else%
            \printchar{#1}{#3}%
            \ifx\relax#2\relax%
            \else%
                \ifx\relax#4\relax%
                \else%
                    ,\edef\@footmp{#2,#4|}%
                    \expandafter\parsefoo\@footmp%
                \fi%
            \fi%
        \fi%
    \fi%
}
\newcommand\foo[2]{% Takes in two strings
    % <begin loop>
    % Extracts out one character from both strings
    \edef\@footmp{#1,#2|}%
    \expandafter\parsefoo\@footmp%
    %\printchar{#1}{#2}%
    % Continue loop until strings run out of characters
    % <end loop>
}
\makeatother

\begin{document}
    \foo{abc}{def} % Should print a,d,b,e,f
    haha
\end{document}

results


The loop will stop when either strings runs out of items.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\foo}{mmm}
 {% #1 is the macro to use, #2 is the first string, #3 is the second string
  \troy_foo:Nnn #1 { #2 } { #3 }
 }

\seq_new:N \l_troy_foo_first_seq
\seq_new:N \l_troy_foo_second_seq

\cs_new_protected:Nn \troy_foo:Nnn
 {
  % split the first string into items
  \seq_set_split:Nnn \l_troy_foo_first_seq { } { #2 }
  % split the second string into items
  \seq_set_split:Nnn \l_troy_foo_second_seq { } { #3 }
  % map over the two string
  \seq_mapthread_function:NNN \l_troy_foo_first_seq \l_troy_foo_second_seq #1
 }
\ExplSyntaxOff

\newcommand{\printchars}[2]{#1#2\par}

\begin{document}

\foo{\printchars}{abc}{def}

\end{document}

enter image description here

A fully expandable variant:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\loopstrings}{mmm}
 {
  \troy_loopstrings:Nnn #1 { #2 } { #3 }
 }
\cs_new:Nn \troy_loopstrings:Nnn
 {
  \__troy_loopstrings:Nffff #1
   { \tl_head:n { #2 } } { \tl_head:n { #3 } }
   { \tl_tail:n { #2 } } { \tl_tail:n { #3 } }
 }

\cs_new:Nn \__troy_loopstrings:Nnnnn
 {
  \bool_lazy_or:nnF { \tl_if_empty_p:n { #2 } } { \tl_if_empty_p:n { #3 } }
   {
    #1{#2}{#3}
    \troy_loopstrings:Nnn #1 { #4 } { #5 }
   }
 }
\cs_generate_variant:Nn \__troy_loopstrings:Nnnnn { Nffff }
\ExplSyntaxOff

\newcommand{\printchars}[2]{#1#2\par}

\begin{document}

\loopstrings{\printchars}{abcd}{1234}

\loopstrings{\printchars}{abc}{1234}

\loopstrings{\printchars}{abcd}{123}

\end{document}

Here's a LuaLaTeX-based solution. (Exact same output as in @egreg's answer, hence no separate screenshot.)

%% to be compiled under LuaLaTeX
\documentclass{article}
\usepackage{luacode} 
\begin{luacode}
  function string_pair ( u , v )
    for i=1,string.len(u) do 
      tex.sprint ( string.sub (u,i,i) .. string.sub (v,i,i) .. "\\par" )
    end
  end
\end{luacode}
\newcommand\foo[2]{\directlua{string_pair(\luastring{#1},\luastring{#2})}}

\begin{document}
\foo{abc}{def}
\end{document} 

Tags:

Loops

Xstring