Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I want to get part of large data. some part of this data is as follows:

data = {{"(100)", -0.033716509`, -0.19824611`, 
    "(101)", -0.026845098`, -0.18296293`, 
    "(102)", -0.021913837`, -0.17231199`}, {"(103)", -0.015043555`,
-0.16745934`, "(104)", -0.0076064845`, -0.16494502`, 
    "(105)", -1.1449175`*^-15, -0.16417456`}, {"(106)", 
    0.0076064845`, -0.16494502`, "(107)", 0.015043555`, -0.16745934`, 
    "(108)", 0.021913837`, -0.17231199`}, {"(109)", 
    0.026845098`, -0.18296293`, "(110)", 0.033716509`, -0.19824611`, 
    "(111)", -0.054776429`, -0.23685639`}, {"(112)", -0.042058374`,
-0.20053958`, "(113)", -0.029721072`, -0.19132756`, 
    "(114)", -0.019094091`, -0.18620841`}, {"(115)", -0.0093881514`,
-0.18374386`, "(116)", -1.4016566`*^-15, -0.18296576`, "(117)", 
    0.0093881514`, -0.18374386`}, {"(118)", 
    0.019094091`, -0.18620841`, "(119)", 0.029721072`, -0.19132756`, 
    "(120)", 0.042058374`, -0.20053958`}, {"(121)", 
    0.054776429`, -0.23685639`, "("}, {}, {"ELE", "CENTROID", 
    "CARTESIAN", "STRESSES", "PRIN", "STRESSES", "PRIN", "STRAINS", 
    "PRINCIPAL", "STRAINS", "YM"}};

I want to get the elements starting from "(111)" to {}. I prefer not to use Flatten simply because I want the output to match the elements levels (but if Flatten is need that is ok). the lists between "(111)" to {} is a variable and can be more or less. what is the best pattern that can take the elements from "(111)" to {}?

Note: This set of data is repeated multiple times in the large data list and I want them all.

Many thanks.

share|improve this question

2 Answers 2

Interesting problem given the need to preserve structure. The first idea that comes to mind:

pull[data_, s_, f_] := data /. {___, {___, s, a___}, b___, f, ___} :> {{s, a}, b, f}

Test:

pull[data, "(111)", {}]
{{"(111)", -0.0547764, -0.236856}, {"(112)", -0.0420584, -0.20054, 
  "(113)", -0.0297211, -0.191328, 
  "(114)", -0.0190941, -0.186208}, {"(115)", -0.00938815, -0.183744, 
  "(116)", -1.40166*10^-15, -0.182966, "(117)", 0.00938815, -0.183744}, {"(118)", 
  0.0190941, -0.186208, "(119)", 0.0297211, -0.191328, "(120)", 
  0.0420584, -0.20054}, {"(121)", 0.0547764, -0.236856, "("}, {}}

From your updated question I think you will want:

pullAll[data_, s_, f_] := 
  Cases[data, {___, {___, s, a___}, b___, f, ___} :> {{s, a}, b, f}, {0, -3}]

The levelspec {0, -3} will cover everything from the entire expression (as used here) to the deepest level at which it is possible for the pattern to match. If you can narrow the range further it will likely improve performance.

share|improve this answer
    
+1 for this one :) –  Mike Honeychurch Jul 15 at 9:38
    
Thanks, @Mike ! :D –  Mr.Wizard Jul 15 at 9:39
    
+1 from me also :) –  Algohi Jul 15 at 9:39
    
@Mr.Wizard can this answer be used in large data where same data above is repeated (the only difference is the numbers not the strings)? I am thinking to use this pattern with Cases. –  Algohi Jul 15 at 9:52
    
@Algohi The only way to know is to try it an see. :^) It should work if the data has the same structure, assuming I understand it. What do you mean about using the pattern with Cases? –  Mr.Wizard Jul 15 at 9:54
PullAll[data_, s_] :=
DeleteDuplicates@Cases[data, {___, s, a__} :> {s, a}]~Join~
  Most@DeleteCases[data, {a_ /; ToExpression@a < ToExpression@s, __}];

PullAll[data, "(116)"]

{{"(116)", -1.40166*10^-15, -0.182966, "(117)", 0.00938815, -0.183744}, {"(118)", 0.0190941, -0.186208, "(119)", 0.0297211, -0.191328, "(120)", 0.0420584, -0.20054}, {"(121)", 0.0547764, -0.236856, "("}, {}}

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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