8
$\begingroup$

I've got data of the type:

list = {"Class","MW","10 - 11"}

which I would like to split into a number of lists based on the number of characters in the second list element. In the above case, the desired output would be:

newlists = {{"Class","M","10-11"},{"Class","W","10-11"}}

StringSplit[list[[2]],""] gets me in the right direction (the string I want to split will always be in the same position in the list); however, I don't know how to thread this new sublist through the original list.

$\endgroup$
5
  • 1
    $\begingroup$ Guessing where you're going with this, you might want to look at Generating schedules/timetables in Mathematica $\endgroup$
    – rm -rf
    Commented Oct 2, 2013 at 15:56
  • $\begingroup$ @rm-rf Wish I had posted this question before writing the grid layout code... $\endgroup$ Commented Oct 2, 2013 at 17:50
  • $\begingroup$ did I really write one of those answers? sloppy stuff... :) $\endgroup$
    – cormullion
    Commented Oct 2, 2013 at 19:27
  • $\begingroup$ @cormullion I found it ironic that a 10k+ rep'er was referring to others as 'experts'. I wonder if SE gives us a way to see what the rep was when a person answered the question. $\endgroup$ Commented Oct 2, 2013 at 19:59
  • 1
    $\begingroup$ @bobthechemist You can find a user's network profile from their site profile. From there, the reputation tab has a nice plot that you can use to quickly find out what the user's rep was on a given date. $\endgroup$
    – rm -rf
    Commented Oct 2, 2013 at 20:24

5 Answers 5

11
$\begingroup$

Here's how you can thread them:

newlists = Thread[{#, Characters@#2, ##3}] & @@ list
(* {{"Class", "M", "10 - 11"}, {"Class", "W", "10 - 11"}} *)
$\endgroup$
2
  • $\begingroup$ Is there a less ambiguous way to map this command over a list of list: Thread[{#, Characters@#2, ##3}]& @@ # & /@ multilists? I don't know how concerned I should be about nested pure functions. $\endgroup$ Commented Oct 2, 2013 at 18:02
  • 1
    $\begingroup$ @bobthechemist Thread[{#, Characters@#2, ##3}] & @@@ multilists you can also add // Flatten[#, 1] & if you need. $\endgroup$
    – Kuba
    Commented Oct 2, 2013 at 19:08
7
$\begingroup$

Here is an approach that doesn't use threading.

data = {"Class", "MW", "10 - 11"};
{a, b, c} = data;
new = {a, #, c} & /@ Characters @ b
{{"Class", "M", "10 - 11"}, {"Class", "W", "10 - 11"}}
$\endgroup$
3
$\begingroup$
Distribute[MapAt[Characters, list, {2}], List] (* or *)
Distribute[MapAt[StringSplit[#, ""]&, list, {2}], List]

{{"Class", "M", "10 - 11"}, {"Class", "W", "10 - 11"}}

$\endgroup$
2
$\begingroup$

Maybe not handy but interesting way to apply automatic threading:

SetAttributes[h, Listable];
h @@ MapAt[Characters, list, {2}] /. h -> List
{{"Class", "M", "10 - 11"}, {"Class", "W", "10 - 11"}}
multilist = {{"Class", "MW", "10 - 11"}, {"Class", "MK", "10 - 11"}}

h @@@ MapAt[Characters, multilist, {All, 2}] /. h -> List
{{{"Class", "M", "10 - 11"}, {"Class", "W", "10 - 11"}}, 
   {{"Class", "M", "10 - 11"}, {"Class", "K", "10 - 11"}}}
$\endgroup$
2
$\begingroup$
fun[u_] := Module[{dow},
  dow = Characters[#[[2]]] &@u;
  ReplacePart[u, 2 -> #] & /@ dow]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.