4
$\begingroup$

I am still a beginner with Mathematica and I have a simple problem with splitting this list:

List1 = {"Id=\"1\"", "PostTypeId=\"1\"", "AcceptedAnswerId=\"2\"", \
"CreationDate=\"2013-11-05T20:22:07.323\"", "OwnerUserId=\"8\"", \
"LastEditorUserId=\"8\"", "Tags=\"<word-choice><articles>\
\"", "Id=\"2\"", "PostTypeId=\"2\"", "ParentId=\"1\"", "CreationDate=\
\"2013-11-05T20:36:02.473\"", "OwnerUserId=\"17\"", \
"LastEditorUserId=\"17\"", "Id=\"3\"", "PostTypeId=\"2\"", "ParentId=\
\"1\"", "CreationDate=\"2013-11-05T20:37:28.327\"", \
"OwnerUserId=\"6\"", "Id=\"4\"", "PostTypeId=\"2\"", \
"ParentId=\"1\"", "CreationDate=\"2013-11-05T20:38:07.760\"", \
"OwnerUserId=\"18\"", "LastEditorUserId=\"8\"", "Id=\"5\"", \
"PostTypeId=\"1\"", "CreationDate=\"2013-11-05T20:46:59.993\"", \
"OwnerUserId=\"18\"", "LastEditorUserId=\"707\"", \
"Tags=\"<etymology><proverbs>\"", "Id=\"6\"", \
"PostTypeId=\"1\"", "AcceptedAnswerId=\"8\"", \
"CreationDate=\"2013-11-05T21:01:56.857\"", "OwnerUserId=\"18\"", \
"LastEditorUserId=\"707\"", \
"Tags=\"<grammar><grammatical-number>\"", "Id=\"8\"", \
"PostTypeId=\"2\"", "ParentId=\"6\"", \
"CreationDate=\"2013-11-05T21:09:18.067\"", "OwnerUserId=\"6\"", \
"LastEditorUserId=\"1243\"", "Id=\"9\"", "PostTypeId=\"2\"", \
"ParentId=\"6\"", "CreationDate=\"2013-11-05T21:15:24.207\"", \
"OwnerUserId=\"22\"", "LastEditorUserId=\"57\"", "Id=\"10\""}

What I would like to do is divide the list in such a way that I have a lists with only: List1 = {{Id1, CreationDate1, Tags1},{Id2, CreationDate2, Tags2},{Id3, CreationDate3, Tags3}...}.

The approach I tried is to split on the >\". Unfortunately this doesn't work. Can someone help me in finding a quick way to do it? (as plus, it would nice if we could get rid of &alt; and > in somehow)

I hereby post the code I used

StringSplit[StringJoin[{List1}], ">\""]

But it doesn't help a lot, since then I have to get back then to the original list with another StringSplit. I am sure there is a smarter way I am not able to see here.

Thanks a lot in advance!

$\endgroup$
  • $\begingroup$ Try Partition[List1,3] $\endgroup$ – mikado May 1 '18 at 20:16
  • $\begingroup$ It doesn't work because not all the records have "Tags". Note: A record is from id to tag (when is present) $\endgroup$ – Carmine Ragone May 1 '18 at 20:25
  • $\begingroup$ StringSplit only works on strings, not lists. $\endgroup$ – user6014 May 1 '18 at 20:40
  • $\begingroup$ @user6014 I am not sure you're right. Take a look to the documentation center. It states that "StringSplit automatically threads over lists of strings:" and uses as example: StringSplit[{"a:b:c:d", "listable:element"}, ":"] which works perfectly. $\endgroup$ – Carmine Ragone May 1 '18 at 21:00
  • 1
    $\begingroup$ Nevermind, my mistake. I apologize. $\endgroup$ – user6014 May 1 '18 at 21:08
6
$\begingroup$

Maybe this does help?

list = Most[List1];
pos = Flatten[Position[StringTake[#, 1 ;; 3] & /@ list, "Id="]];
AppendTo[pos, Length[list] + 1];
data =
  Map[
   Association[Rule @@@ StringSplit[#, "="]] &,
   Internal`PartitionRagged[
    list,
    Differences[pos]
    ]
   ];
data = MapAt[DateObject, data, {All, "CreationDate"}];
newdata = data[[All, {"Id", "CreationDate", "Tags"}]];
newdata = MapAt[
  If[! MissingQ[#], StringReplace[#, {"&lt;" -> "<", "&gt;" -> ">"}],# ] &, 
  newdata, 
  {All, "Tags"}
  ]
$\endgroup$
  • $\begingroup$ This is really nice! The only thing I am sure about is the function To Associations, because on my Mathematica does not exist. Could you please take a look? However, thank you very much for the help! :) $\endgroup$ – Carmine Ragone May 1 '18 at 21:06
  • $\begingroup$ Ah right, one has to load Needs["GeneralUtilities`"]. But I removed ToAssociations altogether. Have look. $\endgroup$ – Henrik Schumacher May 1 '18 at 21:13
  • $\begingroup$ It's perfect, love it! Thanks a lot! $\endgroup$ – Carmine Ragone May 1 '18 at 22:04
  • $\begingroup$ You're welcome! $\endgroup$ – Henrik Schumacher May 1 '18 at 22:04
4
$\begingroup$

uses ReplaceRepeated in a recursive manner to generate the lists

StringReplace[
Cases[List1, 
x_ /; StringStartsQ[x, ("Id" | "CreationDate" | "Tags")]], 
"&gt;" | "&lt;" -> ""] //. {p___, x_ /; StringStartsQ[x, "Id"], y__,z_ /;
StringStartsQ[z, "Id"], t___} :> {p, {x, y}, z, t}

(* {{"Id=\"1\"", "CreationDate=\"2013-11-05T20:22:07.323\"", 
"Tags=\"word-choicearticles\""}, {"Id=\"2\"", 
"CreationDate=\"2013-11-05T20:36:02.473\""}, {"Id=\"3\"", 
"CreationDate=\"2013-11-05T20:37:28.327\""}, {"Id=\"4\"", 
"CreationDate=\"2013-11-05T20:38:07.760\""}, {"Id=\"5\"", 
"CreationDate=\"2013-11-05T20:46:59.993\"", 
"Tags=\"etymologyproverbs\""}, {"Id=\"6\"", 
"CreationDate=\"2013-11-05T21:01:56.857\"", 
"Tags=\"grammargrammatical-number\""}, {"Id=\"8\"", 
"CreationDate=\"2013-11-05T21:09:18.067\""}, {"Id=\"9\"", 
"CreationDate=\"2013-11-05T21:15:24.207\""}, "Id=\"10\""} *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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