Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem using 'in' operator when testing for elements in 2D arrays

Status
Not open for further replies.

Basic Inc

IS-IT--Management
Jul 20, 2017
2
GB
Hi all. I'm stuck on this. I've tried so many combinations I'm dizzy with it now!

I'm trying to test for the presence of an array element in a 2D array (multidimensional array, or array of arrays) without (by default) creating the element. According to the manuals I have us the 'in' operator for this, and it has to be in a plain test (can't be in a for loop). I've spared you the grizzly details of my code and I'm just attaching one liner equivalents (below). I just can't get the test to return 'true'. I'm guessing it's something stupid.

I've tried this in various versions of awk as I'm aware that 'proper' arrays were not introduced until version 4.1 or something. Admittedly, the examples below are using cygwin gawk, but I'm getting the same on all platforms, and the version is OK (see lines at bottom). I'm getting it whether I try to use proper array addressing or awk's original subscript concatenation method; awk or gawk.

Here are some examples. All consist of 2D array element assignment, followed by simple element 'in' array test.

As you can see I've tried quite a few combinations of addressing the element. Supposedly, testing: (i, j) in arr should work (the eighth one down). However, none of these work (none return "yes" when I enter lines):

$ gawk '{arr[2][3]=1; if("2" "\034" "3" in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if(("2" , "3") in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if(("2" SUBSEP "3") in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if(2 "\034" 3 in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if((2 "\034" 3) in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if((2 SUBSEP 3) in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if((2 , 3) in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if((2, 3) in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if((2,3) in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if(("2","3") in arr) print "yes"}'

$ gawk '{arr["2"]["3"]=1; if(("2","3") in arr) print "yes"}'

$ gawk '{arr["2"]["3"]=1; if(("2", "3") in arr) print "yes"}'

$ gawk '{arr["2"]["3"]=1; if(("2" SUBSEP "3") in arr) print "yes"}'

$ gawk '{arr["2"]["3"]=1; if(("2" "\034" "3") in arr) print "yes"}'

$ gawk '{arr["2"]["3"]=1; if(("2" "3") in arr) print "yes"}'

$ gawk '{arr["2"]["3"]=1; if((2 3) in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if((2 3) in arr) print "yes"}'

$ gawk '{arr[2][3]=1; if(("2" "3") in arr) print "yes"}'

Whereas the element is there:

$ gawk '{arr["2"]["3"]=1; if(arr["2"]["3"]==1) print "yes"}'
yes

Here is my gawk version, but as I say, I've tried this on modern Linux (gawk version 4.1) and on awk:


$ gawk --version
GNU Awk 4.1.3, API: 1.1 (GNU MPFR 3.1.4, GNU MP 6.1.0)
Copyright (C) 1989, 1991-2015 Free Software Foundation.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see
 
Hi

You are mixing things there. [tt]SUBSEP[/tt] is specific for old style emulated multidimensional arrays so has no special effect when used on new style real multidimensional arrays.

The best solution I know is to check each dimension separately :
Code:
[blue]master #[/blue] gawk '[teal]{[/teal]arr[teal][[/teal][purple]2[/purple][teal]][[/teal][purple]3[/purple][teal]]=[/teal][purple]1[/purple][teal];[/teal] [b]if[/b][teal]([/teal][purple]2[/purple] [teal]in[/teal] arr [teal]&&[/teal] [purple]3[/purple] [teal]in[/teal] arr[teal][[/teal][purple]2[/purple][teal]])[/teal] [b]print[/b] [i][green]"yes"[/green][/i][teal]}[/teal]' <<< ''
yes


Feherke.
feherke.github.io
 
Hi feherke. That looks like a decent compromise, which I can see should work. Thanks for your contribution.

I'm still interested to hear from others in the forum as to why the simpler: (i, j) in arr construct is not working...

Regards,



 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top