- A+

From a certain point I got tired of writing set conditions (`and`

, `or`

), because for more conditions or longer variable names it begins to be clumsy and annoying to write all over again. So I started writing helpers so I could write `ASet.ContainsOne([ceValue1, ceValue2])`

instead of `(ceValue1 in ASet) or (ceValue2 in ASet)`

.

`type TCustomEnum = (ceValue1, ceValue2, ceValue3); TCustomSet = set of TCustomEnum; TCustomSetHelper = record helper for TCustomSet function ContainsOne(ASet: TCustomSet): Boolean; function ContainsAll(ASet: TCustomSet): Boolean; end; implementation function TCustomSetHelper.ContainsOne(ASet: TCustomSet): Boolean; var lValue : TCustomEnum; begin for lValue in ASet do begin if lValue in Self then Exit(True); end; Result := False; end; function TCustomSetHelper.ContainsAll(ASet: TCustomSet): Boolean; var lValue : TCustomEnum; begin Result := True; for lValue in ASet do begin if not (lValue in Self) then Exit(False); end; end; `

Unfortunately, this is not the most effective solution and it's against the DRY principle. To my surprise, I didn't find anyone ever dealing with the same problem, so I wonder if there is any better (generic) solution?

The set operators help you implement these functions

For `ContainsOne`

we use the `*`

operator which is the set intersection operator.

`function TCustomSetHelper.ContainsOne(ASet: TCustomSet): Boolean; begin Result := ASet * Self <> []; end; `

For `ContainsAll`

we would use `<=`

which is the subset operator.

`function TCustomSetHelper.ContainsAll(ASet: TCustomSet): Boolean; begin Result := ASet <= Self; end; `

Given how simple these expressions are, I question whether or not you need the helper type at all.

The documentation gives the full list of available set operators.