Reputation: 10865
s
, generate a result string with n
(an integer) repeats of s
{"a", "b", "c"}
and {1,0,3}
, I want to have "accc"
.I of course want to have the most efficient way of doing these. Otherwise, my own way is too ugly and slow.
Thank you for your help!
Upvotes: 2
Views: 425
Reputation: 24336
Knowing your application I propose using Inner
:
sets = {{0, 0, 0, 4}, {0, 0, 1, 3}, {0, 1, 0, 3}, {0, 1, 1, 2}, {0, 2, 0, 2},
{0, 2, 1, 1}, {1, 0, 0, 3}, {1, 0, 1, 2}, {1, 1, 0, 2}, {1, 1, 1, 1},
{1, 2, 0, 1}, {1, 2, 1, 0}, {2, 0, 0, 2}, {2, 0, 1, 1}, {2, 1, 0, 1},
{2, 1, 1, 0}, {2, 2, 0, 0}};
chars = {"a", "b", "c", "d"};
Inner[ConstantArray[#2, #] &, sets, chars, StringJoin]
{"dddd", "cddd", "bddd", "bcdd", "bbdd", "bbcd", "addd", "acdd", "abdd", "abcd", "abbd", "abbc", "aadd", "aacd", "aabd", "aabc", "aabb"}
Upvotes: 2
Reputation: 4420
For 1, Table
will do what you need.
s = "samplestring";
StringJoin[Table[s, {3}]]
"samplestringsamplestringsamplestring"
But acl's answer using ContantArray
is faster, if you care about the last 1/100th second.
Do[StringJoin[Table[s, {30}]];, {10000}] // Timing
{0.05805, Null}
Do[StringJoin[ConstantArray[s, 30]];, {10000}] // Timing
{0.033306, Null}
Do[StringJoin[Table[s, {300}]];, {10000}] // Timing
{0.39411, Null}
Do[StringJoin[ConstantArray[s, 300]];, {10000}] // Timing
{0.163103, Null}
For 2, MapThread will handle cases where the second list is known to be non-negative integers.
StringJoin @
MapThread[Table[#1, {#2}] &, {{"a", "b", "c"} , {1, 0, 3}}]
"accc"
If the second list contains negative integers, these are treated as zeros.
Non-integer elements in the second list are treated as if they are the integer part. I am not sure if this is what you want.
StringJoin @
MapThread[Table[#1, {#2}] &, {{"a", "b", "c"} , {1, 0, 3.7}}]
"accc"
Upvotes: 5
Reputation: 6520
rep[s_String, n_] := StringJoin[ConstantArray[s, n]]
then
rep["f", 3]
(*fff*)
next
chars = {"a", "b", "c"};
freqs = {1, 0, 3};
StringJoin[MapThread[rep, {chars, freqs}]]
gives "accc"
Upvotes: 12