I need to string match in the second level of a list but have true cases returned at the first level (there's information in the first level that I need to categorize the returns).
First /@ GatherBy[#, #[[3]] &] &@
Cases[#, x_List /;
MemberQ[x, s_String /;
StringMatchQ[s, ("*PHYSICAL EXAMINATION*"),
IgnoreCase -> True]], {2}] &@
Cases[MemoizeTable["Diagnostic_table.txt"], {_,
11111, __}]
The GatherBy command at the top is just organizing all the entries by date so I don't get any duplicates. Then I ask for cases within the diagnostic table that have terms matching the string "PHYSICAL EXAMINATION".
I have to search only the second level of the lists. If I search just the first I don't return all the true cases. If I search the first and second, I get duplicates (some cases include the desired string at both the first and second levels, so the first and second levels of the list are both returned, separately).
I need to search for the string at the second level and then return ONLY the first level of the lists that contain that matched second level. I don't need to exclude the second level, I just don't want it returned separately like it is if I search levels one and two.
Any help would be much appreciated!
Maybe something like this?
list = {{a, b, c, {x, y}, d, x}, {a, b, c, d, x}, {{a, b, c, d}, x}}
Select[list, MemberQ[#, x, {2}] &]
Output:
{{a, b, c, {x, y}, d, x}}
Update
This will also work
Cases[list, _?(MemberQ[#, x, {2}] &)]
Update to @rose question (see comments)
Given the following data how can I select for entries which contain the words "PHYSICAL EXAMINATION" within a string, for example within the string "P-023 PHYSICAL EXAMINATION, TECHNICIAN, NOS", at the second level (ie only within the sublist)? (I have modified @rose's example somewhat)
rdata2={{1111113,21119,SQLDateTime[{2011,1,11,11,11,0.`}],31111,"EB/JW",1,47000,"T-510 CHEEK",{"T-510 CHEEK","No Examination, NOS"},"Text bla bla bla physical examination bla bla"},{1111114,21119,SQLDateTime[{2011,2,11,11,11,0.`}],31112,"EB/JW",1,47000,"T-510 CHEEK",{"T-510 CHEEK","P-023 PHYSICAL EXAMINATION, TECHNICIAN, NOS"},"Text bla bla bla"},
{1111115,21000,SQLDateTime[{2011,1,11,11,11,0.`}],31111,"EB/JW",1,47000,"T-510 CHEEK",{"T-510 CHEEK","P-023 physical examination, TECHNICIAN, NOS"},"Text bla bla bla physical examination bla bla"}};
(1) One way (returning only entry 1111114)
Select[rdata2,
MemberQ[Characters@#,
Flatten@{___, Characters["PHYSICAL EXAMINATION"], ___}, {2}] &]
(2) Ignore case (but still selecting within sublist)
Select[rdata2,MemberQ[ToLowerCase@Characters@#,
Flatten@{___,ToLowerCase@
Characters["PHYSICAL EXAMINATION"],___},{2}]&]
(selects for entries 1111114 & 1111115)
(3) A final example (select for entries with "No Examination" within sublist but where there may be zero or more characters between "No" and "Examination", and where case is again ignored)
Select[rdata2,
MemberQ[ToLowerCase@Characters@#,
Flatten@Riffle[
ToLowerCase@Characters@{"No", "Examination"}, ___, {1, -1,
2}], {2}] &]
(selects for entry 1111113)
There are no doubt more efficient ways to proceed. I hope I have interpreted the question correctly.
If I understand your requirements, you may consider:
dat = {{1111113, 21119, SQLDateTime[{2011, 1, 11, 11, 11, 0.`}],
31111, "EB/JW", 1, 47000,
"T-510 CHEEK", {"T-510 CHEEK", "No Examination, NOS"},
"Text bla bla bla physical examination bla bla"}, {1111114, 21119,
SQLDateTime[{2011, 2, 11, 11, 11, 0.`}], 31112, "EB/JW", 1,
47000, "T-510 CHEEK", {"T-510 CHEEK",
"P-023 PHYSICAL EXAMINATION, TECHNICIAN, NOS"},
"Text bla bla bla"}, {1111115, 21000,
SQLDateTime[{2011, 1, 11, 11, 11, 0.`}], 31111, "EB/JW", 1, 47000,
"T-510 CHEEK", {"T-510 CHEEK",
"P-023 physical examination, TECHNICIAN, NOS"},
"Text bla bla bla physical examination bla bla"}};
p =
Position[ dat,
_String?(StringMatchQ[#, "*PHYSICAL EXAMINATION*", IgnoreCase -> True] &),
{2, 3}
];
dat[[ Union[First /@ p] ]]