7
$\begingroup$

I'm trying to get better with pattern matching but even after years of using MMA it's still a murky concept. The docs are actually pretty good in this regard but I still struggle. In this situation I have a list of real estate items (that are strings) which I'm trying to clean up. I've tried the below 2 methods and have not been able to delete the "HVAC" elements required from this list.

DeleteCases[featureList, StringContainsQ [#,"HVAC"] & ] 

and

DeleteCases[featureList, __~~"HVAC"~~__] 

Both return the same list back:

{ML #,Property Type,SubSpcSqFt,Land Sz SF,Building Type,List Date,Yr Blt,Address,Area,Class,Clear Ceiling Ht (Feet),Lot Frontage (ft),Lot Depth (ft),Zone,Price,Sale Type,Transaction Type,Zoning/Land Use,Amenities-HVAC System,Building Type-Freestanding,HVAC-See Realtor Remarks,HVAC-Baseboard,HVAC-Central A/C,HVAC-Common Water Heater,HVAC-Electric,HVAC-Forced Air,HVAC-Heat Pump,HVAC-Hot Water,HVAC-In-Floor,HVAC-Make-Up Air,HVAC-Mixed,HVAC-None,HVAC-Radiant,HVAC-Rooftop,HVAC-Separate Controls,HVAC-Separate HVAC Units,HVAC-Separate Water Heaters,HVAC-Space Heaters,HVAC-Steam,HVAC-Window A/C} 

What is the correct way to filter out any string containing "HVAC"?

$\endgroup$
1

7 Answers 7

11
$\begingroup$
featureList = {"ML #", "Property Type", "SubSpcSqFt", "Land Sz SF", "Building Type", "List Date", "Yr Blt", "Address", "Area", "Class", "Clear Ceiling Ht (Feet)", "Lot Frontage (ft)", "Lot Depth (ft)", "Zone", "Price", "Sale Type", "Transaction Type", "Zoning/Land Use", "Amenities-HVAC System", "Building Type-Freestanding", "HVAC-See Realtor Remarks", "HVAC-Baseboard", "HVAC-Central A/C", "HVAC-Common Water Heater", "HVAC-Electric", "HVAC-Forced Air", "HVAC-Heat Pump", "HVAC-Hot Water", "HVAC-In-Floor", "HVAC-Make-Up Air", "HVAC-Mixed", "HVAC-None", "HVAC-Radiant", "HVAC-Rooftop", "HVAC-Separate Controls", "HVAC-Separate HVAC Units", "HVAC-Separate Water Heaters", "HVAC-Space Heaters", "HVAC-Steam", "HVAC-Window A/C"}; 

The following are all equivalent

DeleteCases[featureList, _?(StringContainsQ[#, "HVAC"] &)] DeleteCases[featureList, _?(StringContainsQ["HVAC"])] DeleteCases[featureList, _?(StringMatchQ[#, ___ ~~ "HVAC" ~~ ___] &)] DeleteCases[featureList, _?(StringMatchQ[___ ~~ "HVAC" ~~ ___])] Select[featureList, StringFreeQ["HVAC"]] 
$\endgroup$
2
  • $\begingroup$ It would be fine to add he alternative solution : Select[featureList, ! StringContainsQ[#, "HVAC"] &] $\endgroup$ Commented Mar 7, 2020 at 15:03
  • $\begingroup$ Excellent answer. I found this doc helpful in understanding the behaviour of this answer: reference.wolfram.com/language/ref/PatternTest.html $\endgroup$ Commented Mar 7, 2020 at 16:37
6
$\begingroup$

In addition:

DeleteCases[featureList, str_/;StringContainsQ[str, "HVAC"]] 

But perhaps combined with a regular expression is more powerful?

For example (delete cases where str begins with 'HVAC' only):

 DeleteCases[featureList, str_/;StringContainsQ[str, RegularExpression["^HVAC"]]] 

{ML #, Property Type, SubSpcSqFt, Land Sz SF, Building Type, List Date, Yr Blt, Address, Area, Class, Clear Ceiling Ht (Feet), Lot Frontage (ft), Lot Depth (ft), Zone, Price, Sale Type, Transaction Type, Zoning/Land Use, Amenities-HVAC System, Building Type-Freestanding}

And, of course, there is also Pick

Pick[featureList,StringContainsQ[featureList,"HVAC"],False] 
$\endgroup$
1
  • $\begingroup$ Ah. Good answer too. I was more confused about patterns but there are a lot of regex gurus out there. $\endgroup$ Commented Mar 7, 2020 at 21:32
3
$\begingroup$

DeleteCases require a pattern to remove elements

removes all elements of expr that match pattern.

in your examples, StringContainsQ [#,"HVAC"] & is a function, take a string, return a bool.

so you need _?StringContainsQ [#,"HVAC"] & to get a pattern. Which is called PatternTest


__~~"HVAC"~~__ is called https://reference.wolfram.com/language/ref/StringExpression.html. Yes, in mathematica, string has its own methods.

so you need a function to convert StringExpression to pattern. StringMatchQ + PatternTest works.

something like

featureList // DeleteCases[_?(StringMatchQ[___ ~~ "HVAC" ~~ ___])] 
$\endgroup$
2
$\begingroup$
list = {"ML #", "Property Type", "SubSpcSqFt", "Land Sz SF", "Building Type", "List Date", "Yr Blt", "Address", "Area", "Class", "Clear Ceiling Ht (Feet)", "Lot Frontage (ft)", "Lot Depth (ft)", "Zone", "Price", "Sale Type", "Transaction Type", "Zoning/Land Use", "Amenities-HVAC System", "Building Type-Freestanding", "HVAC-See Realtor Remarks", "HVAC-Baseboard", "HVAC-Central A/C", "HVAC-Common Water Heater", "HVAC-Electric", "HVAC-Forced Air", "HVAC-Heat Pump", "HVAC-Hot Water", "HVAC-In-Floor", "HVAC-Make-Up Air", "HVAC-Mixed", "HVAC-None", "HVAC-Radiant", "HVAC-Rooftop", "HVAC-Separate Controls", "HVAC-Separate HVAC Units", "HVAC-Separate Water Heaters", "HVAC-Space Heaters", "HVAC-Steam", "HVAC-Window A/C"}; 

Using StringDelete and Cases:

Cases[Except[""]]@StringDelete[featureList, ___ ~~ "HVAC" ~~ ___] 

{"ML #", "Property Type", "SubSpcSqFt", "Land Sz SF", "Building Type", "List Date", "Yr Blt", "Address", "Area", "Class", "Clear Ceiling Ht (Feet)", "Lot Frontage (ft)", "Lot Depth (ft)", "Zone", "Price", "Sale Type", "Transaction Type", "Zoning/Land Use", "Building Type-Freestanding"}

Or using StringSplit and Catenate:

Catenate@StringSplit[featureList, ___ ~~ "HVAC" ~~ ___] (*Same result*) 
$\endgroup$
1
  • $\begingroup$ I've downvoted this answer because (1) the question is about using DeleteCases (and how to construct the pattern), and (2) I don't see any benefit in using the two-step solution (Position followed by ReplacePart); it is slower, uses more memory, and is less readable. $\endgroup$ Commented Jun 25, 2024 at 14:32
2
$\begingroup$

Using StringReplace:

ReplaceAll["" -> Nothing]@ StringReplace[featureList, _ ~ "HVAC" ~ _ :> ""] 
$\endgroup$
1
$\begingroup$
list = {"ML #", "Property Type", "SubSpcSqFt", "Land Sz SF", "Building Type", "List Date", "Yr Blt", "Address", "Area", "Class", "Clear Ceiling Ht (Feet)", "Lot Frontage (ft)", "Lot Depth (ft)", "Zone", "Price", "Sale Type", "Transaction Type", "Zoning/Land Use", "Amenities-HVAC System", "Building Type-Freestanding", "HVAC-See Realtor Remarks", "HVAC-Baseboard", "HVAC-Central A/C", "HVAC-Common Water Heater", "HVAC-Electric", "HVAC-Forced Air", "HVAC-Heat Pump", "HVAC-Hot Water", "HVAC-In-Floor", "HVAC-Make-Up Air", "HVAC-Mixed", "HVAC-None", "HVAC-Radiant", "HVAC-Rooftop", "HVAC-Separate Controls", "HVAC-Separate HVAC Units", "HVAC-Separate Water Heaters", "HVAC-Space Heaters", "HVAC-Steam", "HVAC-Window A/C"}; 

Using Delete

p = Position[list, s_String /; StringContainsQ[s, "HVAC"]]; Delete[p] @ list 

{"ML #", "Property Type", "SubSpcSqFt", "Land Sz SF", "Building
Type", "List Date", "Yr Blt", "Address", "Area", "Class", "Clear
Ceiling Ht (Feet)", "Lot Frontage (ft)", "Lot Depth (ft)", "Zone",
"Price", "Sale Type", "Transaction Type", "Zoning/Land Use",
"Building Type-Freestanding"}

$\endgroup$
1
$\begingroup$

Using StringPosition:

list = {"ML #", "Property Type", "SubSpcSqFt", "Land Sz SF", "Building Type", "List Date", "Yr Blt", "Address", "Area", "Class", "Clear Ceiling Ht (Feet)", "Lot Frontage (ft)", "Lot Depth (ft)", "Zone", "Price", "Sale Type", "Transaction Type", "Zoning/Land Use", "Amenities-HVAC System", "Building Type-Freestanding", "HVAC-See Realtor Remarks", "HVAC-Baseboard", "HVAC-Central A/C", "HVAC-Common Water Heater", "HVAC-Electric", "HVAC-Forced Air", "HVAC-Heat Pump", "HVAC-Hot Water", "HVAC-In-Floor", "HVAC-Make-Up Air", "HVAC-Mixed", "HVAC-None", "HVAC-Radiant", "HVAC-Rooftop", "HVAC-Separate Controls", "HVAC-Separate HVAC Units", "HVAC-Separate Water Heaters", "HVAC-Space Heaters", "HVAC-Steam", "HVAC-Window A/C"}; DeleteCases[list, _?(UnequalTo[{}]@*StringPosition["HVAC"])] 

{"ML #", "Property Type", "SubSpcSqFt", "Land Sz SF", "Building
Type", "List Date", "Yr Blt", "Lot Frontage (ft)", "Lot Depth (ft)",
"Zone", "Price", "Sale Type", "Transaction Type", "Zoning/Land Use",
"Building Type-Freestanding"}

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.