Эквивалент Sprintf в Mathematica? - PullRequest
       31

Эквивалент Sprintf в Mathematica?

25 голосов
/ 06 октября 2009

Я не знаю, почему в Википедии перечислен Mathematica как язык программирования с printf . Я просто не мог найти эквивалент в Mathematica.

Моя конкретная задача - обработать список файлов данных с добавленными числами, которые я использовал для этого в bash с

fn=$(printf "filename_%05d" $n)

Ближайшая функция, которую я нашел в Mathematica, - PaddedForm. И после некоторых проб и ошибок я получил это с

"filename_" <> PaddedForm[ Round@#, 4, NumberPadding -> {"0", ""} ]&

Очень странно, что мне нужно использовать число 4, чтобы получить результат, аналогичный тому, который я получаю из "% 05d". Я вообще не понимаю этого поведения. Может кто-нибудь объяснить это мне?

И это лучший способ достичь того, что я использовал в bash?

Ответы [ 5 ]

9 голосов
/ 06 октября 2009

Я бы не использовал PaddedForm для этого. На самом деле, я не уверен, что PaddedForm хорош для всего. Вместо этого я бы использовал старые добрые ToString, Characters и PadLeft, например:

toFixedWidth[n_Integer, width_Integer] := 
  StringJoin[PadLeft[Characters[ToString[n]], width, "0"]]

Тогда вы можете использовать StringForm и ToString, чтобы сделать ваше имя файла:

toNumberedFileName[n_Integer] :=
  ToString@StringForm["filename_``", toFixedWidth[n, 5]]

Mathematica не очень подходит для этого вида струнных жеребьевок.

ИЗМЕНИТЬ, чтобы добавить: Собственно Mathematica не обладает необходимой функциональностью, но класс java.lang.String имеет статический метод format(), который принимает аргументы в стиле printf. Вы можете вызвать его с помощью JLink-функций Mathematica. Производительность не будет очень хорошей, но для многих случаев использования вам будет все равно:

Needs["JLink`"];
LoadJavaClass["java.lang.String"];
LoadJavaClass["java.util.Locale"];
sprintf[fmt_, args___] :=
 String`format[Locale`ENGLISH,fmt,
  MakeJavaObject /@
   Replace[{args},
    {x_?NumericQ :> N@x,
     x : (_Real | _Integer | True | 
         False | _String | _?JavaObjectQ) :> x,
     x_ :> MakeJavaExpr[x]},
    {1}]]

Вам нужно проделать немного больше работы, потому что JLink немного туповат в функциях Java с переменным числом аргументов. Метод format() принимает строку формата и массив Java Object s, и Mathematica не будет выполнять преобразование автоматически, для этого существует MakeJavaObject.

8 голосов
/ 25 августа 2011

Я столкнулся с той же проблемой совсем немного и решил написать свою собственную функцию. Я не делал этого в Java, а просто использовал строковые операции в Mathematica. Это оказалось довольно продолжительным, поскольку мне действительно требовалась функциональность% f, но она работает, и теперь у меня есть пакет, который я могу использовать в любое время. Вот ссылка на проект GitHub:

https://github.com/vlsd/MathPrintF

Он поставляется с инструкциями по установке (на самом деле это просто копирование каталога в $ Path).

Надеюсь, это будет полезно хотя бы для некоторых.

5 голосов
/ 08 июня 2011

Вы также можете определить функцию, которая передает все аргументы в StringForm [] и использовать IntegerString или функции заполнения, как упоминалось ранее:

Sprintf[args__] := StringForm[args__] // ToString;
file = Sprintf["filename_``", IntegerString[n, 10, 5]];
2 голосов
/ 22 октября 2014

IntegerString делает именно то, что вам нужно. В этом случае это будет

IntegerString[x,10,5]
1 голос
/ 18 апреля 2010

Я согласен с Пилси. Вот как бы я это сделал. Обратите внимание на удобную функцию cat, которая, на мой взгляд, похожа на sprintf (за исключением заполнителей, таких как StringForm) в том смысле, что она работает как Print (вы можете печатать любое объединение выражений без преобразования в String), но генерирует строку вместо отправка на стандартный вывод.

cat = StringJoin@@(ToString/@{##})&;

pad[x_, n_] := If[StringLength@cat[x]>=n, cat[x], 
                                          cat@@PadLeft[Characters@cat[x],n,"0"]]

cat["filename_", pad[#, 5]]&

Это очень похоже на ответ Пилси, но я думаю, cat делает его немного чище. Кроме того, я думаю, что безопаснее использовать это условие в функции pad - лучше, если заполнение будет неправильным, чем неправильное число.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...