Register
It is currently Wed Oct 22, 2014 6:39 pm

Reworking arrays to remove highest and lowest numbers


All times are UTC - 6 hours


Post new topic Reply to topic  [ 3 posts ] 
Author Message
 PostPosted: Thu Nov 03, 2011 5:34 pm   

Joined: Tue Jun 28, 2011 4:38 pm
Posts: 7
Hey guys. I am getting a headache trying to figure this out. lol

I have an array of numbers. I need to remove the 2 highest numbers and the 2 lowest numbers then average out the rest.

my array has these numbers:

18562
18252
17862
18005
18480
17972
18166
17592
16851
19705
17667
17553
18434
17496
19712
17484
16916
17659
17829
18287



19705
19712

and

16851
16916

should be removed then the rest of the numbers averaged.

I know I could come up with some real ugly code writing to files and using the sort command and using the grep -v command. But I was hoping there was some secret bash magic out there that could do this succinctly.

Please help :)

~Dynacade


Top
 Profile  
 PostPosted: Fri Nov 04, 2011 4:10 am   
User avatar

Joined: Tue Apr 27, 2010 2:28 pm
Posts: 172
Location: Czech Republic
What's wrong with sort? No file creation is needed, just a pipeline:
Code:
#! /bin/bash
array=(18562
18252
17862
18005
18480
17972
18166
17592
16851
19705
17667
17553
18434
17496
19712
17484
16916
17659
17829
18287)
echo $(
    (IFS=$'\n'; echo "${array[*]}") | sort -n | head -n-2 | tail -n+3 |
        sed '1i('$'\n'';s/$/+/;$s%$%0)/('${#array[@]}'-4)%'
    ) | bc -l


Top
 Profile  
 PostPosted: Wed Nov 09, 2011 7:37 pm   
User avatar

Joined: Wed Jun 08, 2011 8:27 am
Posts: 189
Location: outer Shpongolia
As said choroba, you can use sort(1), then remove the first two and last two integers.
Here is my code:

Code:
#!/bin/bash

nbrs=(
        18562 18252 17862 18005
        18480 17972 18166 17592
        16851 19705 17667 17553
        18434 17496 19712 17484
        16916 17659 17829 18287
     )   

nbrs_size=${#nbrs[@]}
                                                                             
nbrs=( $(printf '%s\n' "${nbrs[@]}" | sort) )

unset 'nbrs[0]' 'nbrs[nbrs_size - 1]' \
      'nbrs[1]' 'nbrs[nbrs_size - 2]'

bc <<< "scale = 2; ($(IFS=+; echo "${nbrs[*]}")) / ($nbrs_size - 4)"


----

dynacade wrote:
[...] I was hoping there was some secret bash magic out there that could do this succinctly.


Not really, but you can implement a sorting algorithm, e.g. Bubble sort,
if you want to make it almost bash(1) only.

Code:
#!/bin/bash                                                                                                                   

sort_array()
{
    # usage: sort_array <array_size> <array>
    if ((! $#)); then
        return 1
    fi 
   
    local arr_size=$1
    shift
    set -f; local arr=($@); set +f
    local _permut=1 _tmp i

    while ((_permut)); do
        _permut=0
       
        for ((i = 0; i < arr_size - 1; i++)); do
            if ((arr[i + 1] < arr[i])); then
                _tmp=${arr[i]}
                arr[i]=${arr[i + 1]}
                arr[i + 1]=$_tmp
               
                _permut=1
            fi 
        done
    done

    echo "${arr[@]}"
}


nbrs=(
        18562 18252 17862 18005
        18480 17972 18166 17592
        16851 19705 17667 17553
        18434 17496 19712 17484
        16916 17659 17829 18287
     )

nbrs_size=${#nbrs[@]}

values=$(sort_array $nbrs_size "${nbrs[@]}")
values=${values#*[[:blank:]]*[[:blank:]]}
values=${values%[[:blank:]]*[[:blank:]]*}
bc <<< "scale = 2; (${values//[[:blank:]]/+}) / ($nbrs_size - 4)"


It'll be slower, though.


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP