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!

Arrays and Perl! 1

Status
Not open for further replies.

arun10427

Programmer
Oct 24, 2009
29
US
Hi all!

i need a simple array help..

For example if my array has (100,0,0,0,0,200,0,0,0,0,0,100) etc..

I wanna read this and populate a new array which would be of the form(100,100,100,100,200,200,200,200,200,100)..zeros will be smoothed out..

Any ideas?
 
Hello,

If you simply want to remove every 0 from the array, use grep.

Code:
my @array2 = grep { $_ > 0 } @array;

Chris
 
You may want to change "$_ > 0" to "$_ != 0" as the former expression may not return values that aren't 0 (i.e. negative values). Although it will work with your example using 100, 200 and 0.

Chris
 
Hi chris,

No I think you got my qn wrong..

I dont wanna remove it..I wanna replace all zeros with the preceding non-zero number
 
@feherke,

Your BLOCK has slightly baffled me. Firstly is $p a special variable? How does perl know to return $p to @array2. I'm also confused how it decides which part of the condition to use, $p=$_ OR $p. How would this be done if 0's were 1's instead?

In attempting to do this differently I tried the code below, and i'm unsure why this doesn't work (possibly something to do with how 0's are perceived):

Code:
my ($marker,@array2);
foreach (@array) {
	if ($marker != 0) {
		$marker = $_;
	}
	push(@array2,$marker);
}
print "@array2";

I have rarely used grep/map, and it seems more complex than I original thought.

Chris
 
@ feherke

Dats JUST awesome!!

How does it do that?

Is there anyway I can smooth it such that..

for eg if my array has

50 0 0 0 0 40

My new array would have 50 50 50 40 40 40

replace first half of 0s with preceding value and de second half of zeros with anteceding values?

 
Zhris,

In response to your question to feherke, $p isn't a special variable (you can declare this as you wish)

Code:
$p= $_ || $p

what this does is take the value of the current iteration variable ... if this is zero, undef or similar it will default to the previous value. In this instance.

100, then 0 or 100 = 100, then 100 or 0 = 100 etc.. etc..

Hope this helps.




Steven Parker
 
arun10427,

What you are asking would involve a more involved algorithm that would look forward to the next x values rather than the next value.

This is hard to specify as I am not sure of your full requirements.

Thanks,

Steven Parker
 
What parkers is asking you is at least an answer to the following questions:
-is the number of 0's variable between two non 0's?
-what to do if that number is not even?
-what to do if the first or the last elements in the array are 0?
and perhaps
-are you 100% sure that all values in the array are strictly numeric?
and perhaps more, depending on your requirements.
BTW you didn't propose any code on your own: what have you tried so far?

Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
Hi

Yeah the number of zeros is variable..And if its even it can be either way..have n-1/2 preceding non zero number and rest anteceding number. all values are strictly numeric..

AND PREX!

What I am doing is reading from a DBF file using Xbase connector and I am trying to smooth out values for better results.. I was jus wondering if copying them into array and manipulating would be a good option.. IF NOT, I can play with the data set..I am not looking for any code nor am I asking you to do my homework..
 
Personally I think interpolating the missing values would be a more sensible approach if you wish to "smooth" the data, something like this:

Code:
[gray]#!/usr/bin/perl -w[/gray]
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]strict[/green][red];[/red]

[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]@array[/blue] = [red]([/red][fuchsia]100[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]200[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]100[/fuchsia],[fuchsia]40[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]0[/fuchsia],[fuchsia]50[/fuchsia][red])[/red][red];[/red]

[black][b]my[/b][/black] [red]([/red][blue]$i[/blue], [blue]$j[/blue], [blue]$k[/blue][red])[/red][red];[/red]
[black][b]my[/b][/black] [blue]$pnz[/blue]=[fuchsia]0[/fuchsia][red];[/red]              [gray][i]# holds previous non-zero index[/i][/gray]

[olive][b]for[/b][/olive] [red]([/red][blue]$i[/blue]=[fuchsia]0[/fuchsia][red];[/red] [blue]$i[/blue] < [url=http://perldoc.perl.org/functions/scalar.html][black][b]scalar[/b][/black][/url] [blue]@array[/blue][red];[/red] [blue]$i[/blue]++[red])[/red] [red]{[/red]
        [olive][b]if[/b][/olive] [red]([/red][blue]$array[/blue][red][[/red][blue]$i[/blue][red]][/red]==[fuchsia]0[/fuchsia][red])[/red] [red]{[/red]
                [gray][i]# look forward to first non-zero[/i][/gray]
                [olive][b]for[/b][/olive] [red]([/red][blue]$j[/blue]=[blue]$i[/blue][red];[/red] [blue]$j[/blue] < [red]([/red][black][b]scalar[/b][/black] [blue]@array[/blue] - [fuchsia]1[/fuchsia][red])[/red] && [blue]$array[/blue][red][[/red][blue]$j[/blue][red]][/red]==[fuchsia]0[/fuchsia] [red];[/red] [blue]$j[/blue]++[red])[/red] [red]{[/red]
[red]}[/red]
                [gray][i]# print interpolated values[/i][/gray]
                [olive][b]for[/b][/olive] [red]([/red][blue]$k[/blue]=[blue]$i[/blue][red];[/red] [blue]$k[/blue] < [blue]$j[/blue][red];[/red] [blue]$k[/blue]++[red])[/red] [red]{[/red]
                        [url=http://perldoc.perl.org/functions/printf.html][black][b]printf[/b][/black][/url] [red]"[/red][purple]%d[purple][b]\n[/b][/purple][/purple][red]"[/red], [blue]$array[/blue][red][[/red][blue]$pnz[/blue][red]][/red] + [red]([/red] [red]([/red][blue]$k[/blue]-[blue]$pnz[/blue][red])[/red]/[red]([/red][blue]$j[/blue]-[blue]$pnz[/blue][red])[/red] [blue]*[/blue] [red]([/red][blue]$[/blue]
[blue]array[/blue][red][[/red][blue]$j[/blue][red]][/red] - [blue]$array[/blue][red][[/red][blue]$pnz[/blue][red]][/red][red])[/red] [red])[/red][red];[/red]
                [red]}[/red]
                [blue]$i[/blue]=[blue]$j[/blue][red];[/red]
        [red]}[/red]
        [black][b]printf[/b][/black] [red]"[/red][purple]%d[purple][b]\n[/b][/purple][/purple][red]"[/red], [blue]$array[/blue][red][[/red][blue]$i[/blue][red]][/red][red];[/red]
        [blue]$pnz[/blue]=[blue]$i[/blue][red];[/red]
[red]}[/red]

Code:
100
120
140
160
180
200
183
166
150
133
116
100
40
42
45
47
50

If the first or last elements of the array are zero, they are treated as significant and interpolation is done to them (i.e. 0,0,50,0,0,0 becomes 0,25,50,33,16,0).

Annihilannic.
 
Annihilannic

Even if it is not what the OP wants, it's a nice solution and I think it is worthy of a star!

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top