Wie muss ich das
\newcounter{dummy} \def\getNoOfElements#1#2{% \setcounter{dummy}{0}% \foreach\dummy in {#1}{\stepcounter{dummy}}% \edef#2{\arabic{dummy}} }
machen, wenn ich die Liste irgendwo definiert habe, z.B. \def\Liste{1,2,3,4}

Öffne in Overleaf
\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\newcounter{dummy}
\def\getNoOfElements#1#2{%
  \setcounter{dummy}{0}% 
  \foreach\dummy in {#1}{\stepcounter{dummy}}%
  \edef#2{\arabic{dummy}}
}
\begin{document}
Geht: 
\getNoOfElements{a,b,c,d,e,f}\No % save the value in \No
\No

~~Geht nicht: 
\def\Liste{1,2,3,4}
\getNoOfElements{\Liste}\No
\No
\end{document}

gefragt 16 Mär '19, 18:25

cis's gravatar image

cis
9.4k26273471
Akzeptiert-Rate: 29%

bearbeitet 16 Mär '19, 18:26


Du möchtest die Macros expandieren, bevor du sie übergibst. Dies geht am einfachsten mittels eines Helfer-Macros:

Öffne in Overleaf
\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\newcounter{dummy}
\makeatletter
\def\getNoOfElements#1#2{%
  \begingroup
  \edef\tmp{#1}%
  \expandafter
  \endgroup
  \expandafter\getNoOfElements@b\expandafter{\tmp}{#2}%
}
\def\getNoOfElements@b#1#2{%
  \setcounter{dummy}{0}% 
  \foreach\dummy in {#1}{\stepcounter{dummy}}%
  \edef#2{\arabic{dummy}}
}
\makeatother
\begin{document}
Geht: 
\getNoOfElements{a,b,c,d,e,f}\No % save the value in \No
\No

~~Geht nicht: 
\def\Liste{1,2,3,4}
\getNoOfElements{\Liste}\No
\No
\end{document}

Zu Prokrastinierungszwecken:

Eine vollständig expandierbare Version des Zählens, die genau 2 Expansionen benötigt. Es gibt zwei Varianten, \getNoOfElements und \getNoOfElementsE, die Erste zählt das Argument unverändert, die Zweite expandiert den ersten Token einmalig. Ich hoffe, der Code ist ausreichend kommentiert.

Öffne in Overleaf
\documentclass[margin=5mm]{standalone}

\makeatletter
% \q@stop ist ein Marker und markiert das Ende der Liste
\def\q@stop{\q@stop}
% führt sein Argument nach \fi aus (schneller als \expandafter\@firstofone)
\long\def\@afterfi#1\fi{\fi#1}
\def\getNoOfElements#1%
  {%
    % irgendwas mit Zahlen
    \the\numexpr
    % ein leeres Argument führt zum Ergebnis 0
    \if\relax\detokenize{#1}\relax
      0%
    \else
      % sonst zählen wir die Anzahl an Kommata und addieren 1 hinzu
      \@afterfi{1\getNoOfElements@#1,\q@stop}%
    \fi
    % \relax beendet \numexpr
    \relax
  }
% zweite Variante, die das Argument einmal expandiert
\def\getNoOfElementsE#1%
  {%
    % irgendwas mit Zahlen
    \the\numexpr
    % ein leeres Argument führt zum Ergebnis 0
    \if\relax\detokenize\expandafter{#1}\relax
      0%
    \else
      % sonst zählen wir die Anzahl an Kommata und addieren 1 hinzu
      \@afterfi{1\expandafter\getNoOfElements@#1,\q@stop}%
    \fi
    % \relax beendet \numexpr
    \relax
  }
\def\getNoOfElements@#1,#2%
  {%
    % überprüfen, ob das Ende der Liste erreicht ist
    \ifx\q@stop#2%
    \else
      % ist die Liste noch nicht beendet, addiere 1 und suche das nächste Komma
      \@afterfi{+1\getNoOfElements@}%
    \fi
  }
\makeatother

\begin{document}
Geht: 
\getNoOfElements{a,b,c,d,e,f} % save the value in \No

~~Geht nicht: 
\def\Liste{1,2,3,4}
\getNoOfElementsE{\Liste}
\end{document}
Permanenter link

beantwortet 16 Mär '19, 22:19

Skillmon's gravatar image

Skillmon
9215
Akzeptiert-Rate: 51%

bearbeitet 16 Mär '19, 23:16

Aja, gut. Aber: Ohgottogott... :()

(16 Mär '19, 22:39) cis

@cis Wieso den Ohgottogott? Lass dich von dem \begingroup und \expandafter\endgroup\expandafter... nicht verwirren. Das ist nur, damit das Macro \tmp nicht versehentlich überschrieben wird, sollte es bereits genutzt sein. Wenn du dir sicher bist, dass dein temporäres Macro nur dir gehört, würde auch \edef\tmp{#1}\expandafter\getNoOfElements@b\expandafter{\tmp} ausreichen.

(16 Mär '19, 22:52) Skillmon
3

@cis Und wenn du das nicht in deinem Macro verankert haben willst, hätte auch in deinem Original \expandafter\getNoOfElements\expandafter{\Liste}\NO als Änderung ausgereicht.

(16 Mär '19, 22:54) Skillmon
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×21

gestellte Frage: 16 Mär '19, 18:25

Frage wurde gesehen: 1,217 Mal

zuletzt geändert: 16 Mär '19, 23:16