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$
7
  • $\begingroup$ Try Partition[List1,3] $\endgroup$
    – mikado
    Commented May 1, 2018 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$ Commented May 1, 2018 at 20:25
  • $\begingroup$ StringSplit only works on strings, not lists. $\endgroup$
    – ktm
    Commented May 1, 2018 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$ Commented May 1, 2018 at 21:00
  • 1
    $\begingroup$ Nevermind, my mistake. I apologize. $\endgroup$
    – ktm
    Commented May 1, 2018 at 21:08

2 Answers 2

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$
4
  • $\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$ Commented May 1, 2018 at 21:06
  • $\begingroup$ Ah right, one has to load Needs["GeneralUtilities`"]. But I removed ToAssociations altogether. Have look. $\endgroup$ Commented May 1, 2018 at 21:13
  • $\begingroup$ It's perfect, love it! Thanks a lot! $\endgroup$ Commented May 1, 2018 at 22:04
  • $\begingroup$ You're welcome! $\endgroup$ Commented May 1, 2018 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 and acknowledge you have read our privacy policy.

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