4
$\begingroup$

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.

$\endgroup$
5
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ @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. $\endgroup$ – Algohi Jul 15 '14 at 9:52
  • $\begingroup$ @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? $\endgroup$ – Mr.Wizard Jul 15 '14 at 9:54
  • $\begingroup$ I mean some thing like this: Cases[my large data, {___, { ___ , s_, a___}, b___, f_, ___} :> {{s, a}, b, f}] $\endgroup$ – Algohi Jul 15 '14 at 9:55
  • $\begingroup$ @Algohi Are you saying this pattern appears multiple times in your actual data? $\endgroup$ – Mr.Wizard Jul 15 '14 at 9:59
  • $\begingroup$ @Mr.Wizard yes exactly you are correct. this pattern is repeated several times. $\endgroup$ – Algohi Jul 15 '14 at 10:01
1
$\begingroup$
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, "("}, {}}

$\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.