LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-21-2006, 07:15 AM   #1
Jus144tice
LQ Newbie
 
Registered: Oct 2006
Posts: 5

Rep: Reputation: 0
Bash Scripting - Accessing Array Indices


I have a non-contiguous array where the array index describes a numeric representation of the corresponding server which is stored in the array at that position.

I have a loop to traverse through the array and I would like for it to print out at what index that server was located, but I can't find out how to do this. A simplified example:
Code:
db[2]="server1"
db[7]="server2"
db[347]="server3"
db[888]="server4"

lookingFor="server3"

for server in ${db[@]}
do 
  if [ $server -eq $lookingFor ] 
    then 
    index="???" #How do I access the array index??
    echo "$server found at index $index" 
  fi 
done

Last edited by Jus144tice; 10-21-2006 at 07:17 AM.
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 10-21-2006, 08:06 AM   #2
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 61
Is this what you have in mind?
Code:
#!/bin/bash

db[2]="server1"
db[7]="server2"
db[347]="server3"
db[888]="server4"
lookingFor="server3"

for server in ${db[@]} ; do
   let index=$index+1
      if [ $server == $lookingFor ] ; then
         echo "$server found at index$index"
     fi
done
 
Old 10-21-2006, 09:46 AM   #3
Jus144tice
LQ Newbie
 
Registered: Oct 2006
Posts: 5

Original Poster
Rep: Reputation: 0
Yes, that will work, however, it is horribly inefficient since I need to traverse 888 values for i, when the size of the array is only 4. If that is the only way to do it, then there should not even be non-contiguous arrays in the language. Here's what I want to do in php:
Code:
$db[2]="server1"
$db[7]="server2"
$db[347]="server3"
$db[888]="server4"
$lookingFor="server3"

for ($db as $index => $server)
{
  if ($server == $lookingFor)
  {
    echo "$server found at index $index\n"
  }
}
Basically, I want to be able to treat the array as a hash table and access the key and the element at each position of the table.
 
Old 10-21-2006, 11:31 AM   #4
jlinkels
LQ Guru
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195

Rep: Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043
The array is contiguous, but the index is not. As a matter of fact, the index can be anything, and "4" is exactly as valid as a fifth element as is "87634786".

The mistake (if I may call it like this, it is not really a mistake) you make is that you use integers to traverse up to the value of 888.

If you really want to use indices like this, I would recommend to create a second array containing a hash table:

hash[0]=2
hash[1]=7
hash[2]=347
hash[3]=888

I don't know how you obtained values like "347" and "888" etc, but it should be possible to put those values in the hash array. Now you can traverse the hash array instead from 0 -> 3, and use the values to index your original array.

jlinkels
 
Old 10-21-2006, 11:45 AM   #5
Jus144tice
LQ Newbie
 
Registered: Oct 2006
Posts: 5

Original Poster
Rep: Reputation: 0
The thought had occurred to me to use two arrays, one for the index (really server ID number) and other for server name. I may end up doing that if I can't find a way to do what I really want. I'm not convinced that the arrays are contiguous but the indices are not. Take this, for example:
Code:
$db[2]="server1"
$db[7]="server2"
$db[347]="server3"
$db[888]="server4"

echo "Array size = ${#db[*]}"
This prints out Array size = 4. If what you say was true, you would think that the previous code would print Array size = 889. That's why I still believe that if the language is smart enough to handle non-contiguous array indices and still know how many elements are in the array (I'm assuming it doesn't traverse through all possible indices and look for non-null values), then it must be smart enough to tell me what the index (or key) is for the value I am using.

Of course, I could be wrong and that's just the way the language works. But if anyone has a solution or even further clarification, please post it. Thanks.
 
Old 10-22-2006, 08:44 PM   #6
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Maybe you should look at it like this.
A pure array eg in C or Bash, works purely on integer element indexes and you can't easily go straight to a given element unless you already know the index value.
In PHP, the arrays are really implented as hashes, but you can also use numeric indexes and treat them as arrays.
FYI, in Perl you have arrays and hashes as (different) basic data types anyway.
HTH
 
Old 10-22-2006, 09:20 PM   #7
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Bash arrays aren't strictly "pure arrays", as they can be sparse.

I don't know of a way to get the indices of the populated slots, but here is a simple way to extract all of them.

Just copy the sparse array to a regular array like this:
Code:
#!/bin/bash

db[2]="server1"
db[7]="server2"
db[347]="server3"
db[888]="server4"

copy=( "${db[@]}" )

echo "Array size= ${#db[*]}"
echo "Copy size= ${#copy[*]}"

for i in $(seq 0 $(expr ${#copy[*]} - 1 ) )
do
  echo "copy[$i]=${copy[$i]}"
done
 
Old 01-10-2015, 03:39 PM   #8
gnypp45
LQ Newbie
 
Registered: Jan 2015
Posts: 1

Rep: Reputation: Disabled
Answer to the OP

I know that many years have passed, but since the OP's original question hasn't yet been given a succinct, to-the-point answer I will present a solution here.

The trick is to use an exclamation mark in front of the array variable name to get the corresponding array of indices:
Code:
echo ${!db[@]}
This produces the following output:

2 7 347 888

The complete code answering the OP question becomes:
Code:
#! /bin/bash

db[2]="server1"
db[7]="server2"
db[347]="server3"
db[888]="server4"

lookingFor="server3"

for i in ${!db[@]}
do 
    if [ "${db[$i]}" = "$lookingFor" ] 
    then
        echo "${db[$i]} found at index $i" 
    fi 
done
This program loops only through the four defined indices and produces the output

server3 found at index 347
 
2 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem Accessing Large RAID Array FlyingPenguin128 Debian 1 05-16-2005 10:51 PM
Help accessing data on NTFS raid array Qwindelzorf Linux - Hardware 2 01-15-2005 02:34 PM
Shell scripting - Adding many numbers in an array Stingreen Linux - General 2 10-25-2004 05:25 PM
Java help (accessing array elemonts from another class or method) Tru_Messiah Programming 6 05-14-2004 09:20 AM
PHP: accessing unnamed array mrtwice Programming 8 04-28-2004 11:14 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:16 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration