Alternative to multiple -OR conditions in an IF-THEN-ELSE statement

I have a [simplified] CSV file with 3 properties. Sample (subset of real data):

Person,Amount,Category
Joe,5,Coffee
Mary,15,Gas
John,25,Food
John,10,Beer
Mary,8,Juice

 

PS code to process the above CSV is:
$data = Import-CSV
$data | Foreach-object -Process {
[pscustomobject]@{Amount=$_.Amount; Person=$_.Person;
Category=If((($_.Category).Contains('coffee') -EQ $True) -OR
(($_.Category).Contains('tea')- EQ $True) -OR
(($_.Category).Contains('soda') EQ $True) -OR
(($_.Category).Contains('beer') -EQ $True) -OR
(($_.Category).Contains('juice') -EQ $True) -EQ $True) {
'drink-'+$_.Category} else {$_.Category}
}
While it works fine, I am wondering if the five (5) -OR statements for testing the condition is the "Powershell way" of doing it. I was considering the use of a hash table, but started with this as a first step.
Would be grateful for any guidance, tips or advice.
Much thanks,

Sorry, please ignore this [2nd] post (but not the original post above).

Not intended to be a reply to the above but as a separate post.

 

I recommend you work on formatting your code in a more readable format.
Also identify and note the 4 different syntax errors in the code above.
The -in operator would replace multiple -eq operators in this case as in:

# $data = Import-Csv .\filename.ext

#region
$data = @()
$data += [PSCustomObject]@{
    Person   = 'Joe'
    Amount   = 5
    Category = 'Coffee'
}
$data += [PSCustomObject]@{
    Person   = 'Mary'
    Amount   = 15
    Category = 'Gas'
}
$data += [PSCustomObject]@{
    Person   = 'John'
    Amount   = 25
    Category = 'Food'
}
$data += [PSCustomObject]@{
    Person   = 'John'
    Amount   = 10
    Category = 'Beer'
}
$data += [PSCustomObject]@{
    Person   = 'Mary'
    Amount   = 8
    Category = 'Juice'
}
#endregion

$CategoryList = $data.Category # or $CategoryList = @('Coffee','Cheese')
$data | Foreach-object -Process {
    [pscustomobject]@{
        Person   = $_.Person
        Amount   = $_.Amount
        Category = $( If ($_.Category -in $CategoryList ) { 'drink-'+$_.Category } else { $_.Category } )
    }
}

Many thanks Mr Boutros. The code shown was the result of a Copy-Paste directly from VSCode editor, which in its original form was neatly formatted. I don’t understand why this led to the left-justified result and the syntax error (the blank character in VSCode, it seems, shows as a centered dot.). My apologies for this. Secondly, I gave the sample data of just 5 lines to illustrate the nature of my question. But I still haven’t found a way to type line by line sample data without the extra space. In fact I just posted a question for this in the feedback forum. The main purpose of the code I submitted was to convert the values of all the 5 categories of property Category (as it originated from the source) from: (coffee,tea,soda,juice,beer) to (drink-coffee,drink-tea,drink-soda,drink-juice,drink-beer).

Thanks again for your reply.

Within the help of calculated property and regex.

$Category = @{
    E = {
        if($_.Category -match "tea|soda|beer|juice"){
            "Drink " + $_.Category
        }
        else{
            $_.Category
        }
    }
    L = 'Category'
}
$data = Import-Csv | Select-Object -Property Amount,Person,$Category

@Ramon,

Kvprasoon’s solution is very good and I would go for that.

However, just for information, you don’t need all those -EQ True, because every expression inside the if condition is already evaluated as $true or $false.

For example:

PS C:\> @('blue','red').Contains('blue')
True

PS C:\> @('blue','red').Contains('black')
False

PS C:\> 

Therefore, this gives the same result as your original code:

Category=If(($_.Category).Contains('coffee') -OR
($_.Category).Contains('tea') -OR
($_.Category).Contains('soda') -OR
($_.Category).Contains('beer') -OR
($_.Category).Contains('juice')) {
'drink-'+$_.Category}
else {$_.Category}

I don’t see how the original code can work, since .contains() is case sensitive. Anyway:

Import-Csv food.csv | Foreach {
  [pscustomobject]@{
    Amount = $_.Amount
    Person = $_.Person
    Category = if ($_.category -in 'coffee','tea','soda','beer','juice') {
      'drink-' + $_.Category}
    else {
      $_.Category}
  }
}


Amount Person Category
------ ------ --------
5      Joe    drink-Coffee
15     Mary   Gas
25     John   Food
10     John   drink-Beer
8      Mary   drink-Juice

or:

if ($_.category -match 'coffee|tea|soda|beer|juice') {

or:

if ('coffee','tea','soda','beer','juice' -contains $_.category) {

You can actually use -eq (or -match or -like) with a list, and it will return the thing in the list from the 2nd arg and end up being true:

PS /Users/js> 'coffee','tea','soda','beer','juice' -eq 'coffee'                  
coffee
PS /Users/js> 'coffee','tea','soda','beer','juice' -eq 'coffee2'                 
PS /Users/js> 

if ('coffee','tea','soda','beer','juice' -eq $_.category) {

Mr Kvprasoon,

Your suggestion is very neat! I’m highly grateful for your solution.

Much thanks.

Many thanks Mr Fullenwarth,

Your examples are very useful and educational to me.

Best,

Yes JS is right: the Contains method is case sentitive.
And in addition, it must also match the whole element.

PS C:\> @('blue','red').Contains('blue')
True

PS C:\> #Case sensitive
@('blue','red').Contains('BLUE')
False

PS C:\> #Does not match the whole element
@('blue','red').Contains('blu')

False

PS C:\> 

Note, VSCode, does include some random stuff that messes up copy / paste for forums and Q&A sites like this.

So, sure format in VSCode, but copy to notepad and check before you submit / post, otherwise use GitHub, paste in, etc… to link to your code.

This sites’, formatting code tags are what you should use when posting, and VSCode, the ISE and other tools do not do this automatically for obvious reasons. Meaning various sites, can and will have different formatting requirements.

Create yourself the necessary shortcuts in VSCode to use the formatting tags required by the sites you post to.

My sincerest gratitude to you all - Messrs. KVprasoon, Fullenwarth, Boutros, JS, Postanote.

I am very thankful that besides giving me excellent answers/solutions, you have also shared many interesting aspects of Powershell and provided numerous insights. Best,