473,765 Members | 1,940 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to walk array and delete matched elements?

I'm kind of lost on this one - I need to modify 2 files based on user input:

$data_array = file($data_file );
$counter_array = file($counter_f ile);
// There is a line-for-line relationship between the data and counter files
//for example, if the 3rd line in the counter file is deleted,
//so also must the 3rd line of the data file be deleted.
// Each line of the data_file has 4 items:
//date|ip_address |user_id|url
for ( $i=0; $i < count($data_arr ay); $i++ )
$data_line = fgets($data_arr ay); //look at each line in data_array
$data = explode("|",$da ta_line);
if ( $data[1] = $ip ) //$ip is user input
{
array_pop($data _array, $data_line);
array_pop($coun ter_array[$i];
//not sure array_pop is correct function here - the manual says this
//will pop element from the bottom of the array, but I need
//to delete this particular element from the middle of the array.
//What is the best way to do this?
}

The goal is to create 2 new files. If the original files look like this:

[data_file]
3/4/04|20.123.112.2 1|grebos|http://www.asc.com
6/5/04|183.40.99.14 |boris|http://www.asc.com
7/16/04|133.73.115.2 9|grebos|http://www.asc.com

[counter file]
2345
1356
5466

and the user selected to remove IP 183.40.99.14, then the new files should
look like this:

[data_file]
3/4/04|20.123.112.2 1|grebos|http://www.asc.com
7/16/04|133.73.115.2 9|grebos|http://www.asc.com

[counter file]
2345
5466

I'm still kind of green when it comes to working with arrays... any help is
appreciated... Thanks.
Jul 17 '05 #1
19 3699
deko <ww************ *************** ****@nospam.com > wrote:
I'm kind of lost on this one - I need to modify 2 files based on user input:

8< -- long snip -- >8

<http://de3.php.net/array_splice> should do the job.

--
Simon Stienen <http://dangerouscat.ne t> <http://slashlife.de>
»What you do in this world is a matter of no consequence,
The question is, what can you make people believe that you have done.«
-- Sherlock Holmes in "A Study in Scarlet" by Sir Arthur Conan Doyle
Jul 17 '05 #2
> <http://de3.php.net/array_splice> should do the job.

Yes, but when the matched element appears twice in a row (that is, in two
lines immediately following each other in datafile.txt), the second one is
not removed from the array. I think this is because the array pointer is
being reset with each loop. Any suggestions on how to correct this?

$data_array = file(datafile.t xt);
$counter_file = file(counterfil e.txt);
//$ip = user defined

for ( $i=0; $i < count($data_arr ay); $i++ )
{
$data_line = $data_array[$i];
$data = explode("|", $data_line); //data_line format:
date|ip_address |user_id|url
if( in_array($ip, $data) )
{
array_splice($d ata_array,$i,1) ;
array_splice($c ounter_array,$i ,1);
}
}
Jul 17 '05 #3
deko <ww************ *************** ****@nospam.com > wrote:
<http://de3.php.net/array_splice> should do the job.


Yes, but when the matched element appears twice in a row (that is, in two
lines immediately following each other in datafile.txt), the second one is
not removed from the array. I think this is because the array pointer is
being reset with each loop. Any suggestions on how to correct this?

$data_array = file(datafile.t xt);
$counter_file = file(counterfil e.txt);
//$ip = user defined

for ( $i=0; $i < count($data_arr ay); $i++ )
{
$data_line = $data_array[$i];
$data = explode("|", $data_line); //data_line format:
date|ip_address |user_id|url
if( in_array($ip, $data) )
{
array_splice($d ata_array,$i,1) ;
array_splice($c ounter_array,$i ,1);
}
}


You mustn't increment after removing an element:

if x == 'b' || x == 'c' -> remove:

i=0.
A B C D E
^-- not removed, i->1

i=1
A B C D E
^-- remove, i->2, data->A C D E

i=2
A C D E
^-- oops, missed the one which fills the hole the previosly deleted
element left...

--
Simon Stienen <http://dangerouscat.ne t> <http://slashlife.de>
»What you do in this world is a matter of no consequence,
The question is, what can you make people believe that you have done.«
-- Sherlock Holmes in "A Study in Scarlet" by Sir Arthur Conan Doyle
Jul 17 '05 #4
"deko" <ww************ *************** ****@nospam.com > wrote in message
news:bG******** *******@newssvr 13.news.prodigy .com...
I'm kind of lost on this one - I need to modify 2 files based on user input:
$data_array = file($data_file );
$counter_array = file($counter_f ile);
// There is a line-for-line relationship between the data and counter files //for example, if the 3rd line in the counter file is deleted,
//so also must the 3rd line of the data file be deleted.
// Each line of the data_file has 4 items:
//date|ip_address |user_id|url
for ( $i=0; $i < count($data_arr ay); $i++ )
$data_line = fgets($data_arr ay); //look at each line in data_array
$data = explode("|",$da ta_line);
if ( $data[1] = $ip ) //$ip is user input
{
array_pop($data _array, $data_line);
array_pop($coun ter_array[$i];
//not sure array_pop is correct function here - the manual says this
//will pop element from the bottom of the array, but I need
//to delete this particular element from the middle of the array.
//What is the best way to do this?
}

The goal is to create 2 new files. If the original files look like this:

[data_file]
3/4/04|20.123.112.2 1|grebos|http://www.asc.com
6/5/04|183.40.99.14 |boris|http://www.asc.com
7/16/04|133.73.115.2 9|grebos|http://www.asc.com

[counter file]
2345
1356
5466

and the user selected to remove IP 183.40.99.14, then the new files should
look like this:

[data_file]
3/4/04|20.123.112.2 1|grebos|http://www.asc.com
7/16/04|133.73.115.2 9|grebos|http://www.asc.com

[counter file]
2345
5466

I'm still kind of green when it comes to working with arrays... any help is appreciated... Thanks.


The function you need is array_filter().
Jul 17 '05 #5
> The function you need is array_filter().

Well, I came up with the below code which is kind of a brute force way to do
it - but it works.
I looked up array_filter in the manual - perhaps it could be used in place
of the first if statement?

<?php
$data_file = "/path/to/data.txt";
$counter_file = "/path/to/counter.txt";
//need to reverse arrays because files are not the same length
//but there is a line-to-line relationship starting from the bottom
$data_array_asc ending = file($data_file );
$data_array = array_reverse($ data_array_asce nding);
$counter_array_ ascending = file($counter_f ile);
$counter_array = array_reverse($ counter_array_a scending);
$d = count($data_arr ay);
echo $d." elements in data_array log\n\n";
$ip = "68.122.35.157" ;
while ( $d > $e )
{
$d = count($data_arr ay);
for ( $i=0; $i < count($data_arr ay); $i++ )
{
$data_line = $data_array[$i];
$data = explode("|", $data_line);
//each line of data.txt has several elements separated by "|"
if( in_array($ip, $data) )
{
array_splice($d ata_array,$i,1) ;
array_splice($c ounter_array,$i ,1);
$c++;
$removed = $data_line.$rem oved;
}
}
$e = count($data_arr ay);
if ( $removed && $d == $e )
{
echo $c." elements removed:\n\n".$ removed."\n\n";
}
}
echo $e." elements in data_array\n\n" ;
$data_array_scr ubbed = array_reverse($ data_array);
$fp = fopen($data_fil e,"w");
foreach($data_a rray_scrubbed as $var)
{
fwrite($fp, $var);
}
fclose($fp);
$counter_array_ scrubbed = array_reverse($ counter_array);
$fp = fopen($counter_ file,"w");
foreach($counte r_array_scrubbe d as $var)
{
fwrite($fp, $var);
}
fclose($fp);
?>
Jul 17 '05 #6
"deko" <ww************ *************** ****@nospam.com > wrote in message
news:%t******** ********@newssv r13.news.prodig y.com...
The function you need is array_filter().
Well, I came up with the below code which is kind of a brute force way to

do it - but it works.
I looked up array_filter in the manual - perhaps it could be used in place
of the first if statement?


What I would do is this: Pass both arrays to array_map(), with null as the
callback function. You will end up with an array with the following
structure:

Array
(
[0] => Array
(
[0] => 3/4/04|20.123.112.2 1|grebos|http://www.asc.com
[1] => 2345
)

[1] => Array
(
[0] => 6/5/04|183.40.99.14 |boris|http://www.asc.com
[1] => 5466
)
)

Write a function that decides whether an element should be removed. It'll
need to get the IP address via a global variable because array_filter()
doesn't let you pass data to the callback. Or if you want to be more
elegant, define a lamda function with create_function () that looks for that
specific IP. Anyway, the function would look something like this:

function NotMatchIP($a) {
global $ip;
$data_line = $a[0];
$data = explode("|", $data_line);
return ($ip != $data[1]);
}

Pass the combined array to array_filter() using this function as the
callback. The array returned will contain the scrubbed content for both
files. Just loop through it and write to both at the same time.

The trick here is the use of array_map(). Working with one array is
obviously easier than two.
Jul 17 '05 #7
> What I would do is this: Pass both arrays to array_map(), with null as the
callback function. You will end up with an array with the following
structure:

Array
(
[0] => Array
(
[0] => 3/4/04|20.123.112.2 1|grebos|http://www.asc.com
[1] => 2345
)

[1] => Array
(
[0] => 6/5/04|183.40.99.14 |boris|http://www.asc.com
[1] => 5466
)
)
So, this is a multi-dimensional array, correct?
Write a function that decides whether an element should be removed. It'll
need to get the IP address via a global variable because array_filter()
doesn't let you pass data to the callback. Or if you want to be more
elegant, define a lamda function with create_function () that looks for that specific IP. Anyway, the function would look something like this:

function NotMatchIP($a) {
global $ip;
$data_line = $a[0];
$data = explode("|", $data_line);
return ($ip != $data[1]);
}
is this a lamda function? What is a lamda function?

Pass the combined array to array_filter() using this function as the
callback. The array returned will contain the scrubbed content for both
files. Just loop through it and write to both at the same time.
This sounds interesting - I'll give it a shot.
The trick here is the use of array_map(). Working with one array is
obviously easier than two.

Jul 17 '05 #8
deko <ww************ *************** ****@nospam.com > wrote:
What I would do is this: Pass both arrays to array_map(), with null as the
callback function. You will end up with an array with the following
structure:

Array
(
[0] => Array
(
[0] => 3/4/04|20.123.112.2 1|grebos|http://www.asc.com
[1] => 2345
)

[1] => Array
(
[0] => 6/5/04|183.40.99.14 |boris|http://www.asc.com
[1] => 5466
)
)


So, this is a multi-dimensional array, correct?


Correct.
Write a function that decides whether an element should be removed. It'll
need to get the IP address via a global variable because array_filter()
doesn't let you pass data to the callback. Or if you want to be more
elegant, define a lamda function with create_function () that looks for
that specific IP. Anyway, the function would look something like this:

function NotMatchIP($a) {
global $ip;
$data_line = $a[0];
$data = explode("|", $data_line);
return ($ip != $data[1]);
}


is this a lamda function? What is a lamda function?


No. As soon as you use the control word "function" you have a named
function (here: NotMatchIP). A lambda function is an unnamed function,
created by create_function () and *only* by create_function ().
While you can call a named function using it's name (here:
MotMatchIp($foo )), you can't call a lambda function the same way, since it
has no name. Instead, you have a variable containing the function, calling
the variable with your parameters:
-----BEGIN PHP CODE BLOCK-----
$my_unnamed_fun ction = create_function ('$x','echo $x+1;');
$my_unnamed_fun ction(5); // outputs 6. notice the preceding dollar sign
$echo_next_inte ger = $my_unnamed_fun ction;
$echo_next_inte ger(17); // outputs 18.
------END PHP CODE BLOCK------

I am not sure about this, but I guess, that internally the concept of PHPs
"function pointers" is used, like in:
-----BEGIN PHP CODE BLOCK-----
$trigonomical_f unction = 'sin'; // string!
echo $trigonomical_f unction($x); // calls sin($x)
------END PHP CODE BLOCK------
Therefore echo $my_unnamed_fun ction should give you the internally used
name of the function. (Which is of no use, since it might change from one
parsing of the script to the next... It's just a technical detail.)

As you can see, you can "copy" the function to another variable, so you
could create whole bunches of functions, saving them in an array and
applying them one after another. All you have to do is to define a API of
parameters which will be used and returned:
-----BEGIN PHP CODE BLOCK-----
// define a function
function square($x) {
return $x*$x;
}

// list functions to use
$funcs = array(
'sin', // internal function
'square', // user-defined function
create_function ('$x','return $x*2') // lambda function
);

// output results
foreach ($funcs as $funcname)
echo $funcname . '(10) is: ' . $funcname(10) . chr(13);
------END PHP CODE BLOCK------
(Note: Every of these functions takes exactly one number.)

HTH
Simon
--
Simon Stienen <http://dangerouscat.ne t> <http://slashlife.de>
»What you do in this world is a matter of no consequence,
The question is, what can you make people believe that you have done.«
-- Sherlock Holmes in "A Study in Scarlet" by Sir Arthur Conan Doyle
Jul 17 '05 #9
> > is this a lamda function? What is a lamda function?

No. As soon as you use the control word "function" you have a named
function (here: NotMatchIP). A lambda function is an unnamed function,
created by create_function () and *only* by create_function ().
While you can call a named function using it's name (here:
MotMatchIp($foo )), you can't call a lambda function the same way, since it
has no name. Instead, you have a variable containing the function, calling
the variable with your parameters: .... snip ... I am not sure about this, but I guess, that internally the concept of PHPs
"function pointers" is used, like in: .... snip ... Therefore echo $my_unnamed_fun ction should give you the internally used
name of the function. (Which is of no use, since it might change from one
parsing of the script to the next... It's just a technical detail.)

As you can see, you can "copy" the function to another variable, so you
could create whole bunches of functions, saving them in an array and
applying them one after another. All you have to do is to define a API of
parameters which will be used and returned:


Thanks for the info - I appreciate the feedback.

The problem with using a multi-dimensional array is that the 2 files are
different lengths. I need to create both arrays individually to do stuff in
an earlier section of the script, so it's easy enough to reverse them and
start from the bottom. As long as the array keys stay in sync, it should
work...

$data_array_r = array_reverse($ data_array);
$counter_array_ r = array_reverse($ counter_array);
$d = count($data_arr ay_r) - 1; // there's a reason for -1
echo "Starting with ".$d." entries<br><br> ";
while ( $d > $s )
// $d>$s causes the while loop
//to run at least twice - so if there
//are 2 entries in a row in data_array
//that need to be spliced out,
//the second one isn't missed
//due to the array pointer reseting
//with each for loop.
{
$d = count($data_arr ay_r) - 1;
for ( $i=0; $i < $d; $i++ )
{
$data_line = $data_array_r[$i];
$data = explode("|", $data_line);
if( in_array($ip, $data) )
{
// here's where the 2 in a row problem arises
array_splice($d ata_array_r,$i, 1);
array_splice($c ounter_array_r, $i,1);
$n++;
$removed = $data_line."<br >".$removed;
}
}
$s = count($data_arr ay_r) - 1;
if ( $removed && $d == $s )
{
echo $n." entries removed:<br><br >".$removed."<b r>";
}
}
echo "Ending with ".$s." entries<br>";
Jul 17 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
3651
by: pembed2003 | last post by:
Hi, I have a question about how to walk a binary tree. Suppose that I have this binary tree: 8 / \ 5 16 / \ / \ 3 7 9 22 / \ / \ / \
18
2482
by: Dan | last post by:
hello, I would to know if it is possible to delete an instance in an array, The following does not allow me to do a delete. I am trying to find and delete the duplicate in an array, thanks for ( j =0; j<MAX ; j++) { for ( i =0; i<MAX ; i++)
13
2350
by: J. J. Cale | last post by:
I have the following. There must be something less cumbersome without push pop. The function parameter obj is the event.srcElement and has the attributes(properties?) picNum and alb pinned to it. The function is part of a process to delete the selected obj, a photo in this case from the album vis albumArr. TIA Jimbo function Album(albumName) { this.name=albumName; this.paths=new Array(); }
5
6385
by: effendi | last post by:
I wrote a simple script to remove an element of an array but I don't think this is the best way to go about it. I have a list of about five elements seperated by ";" I split the array using array.split(";") command and proceeded to update the elemment by assigning the null value to the arrayindex array=""
3
6937
by: Newcomsas | last post by:
Hello, I'm trying to solve a problem with JS textbox array without success. I have two buttons in my page: PLUS and MINUS; at every click on PLUS a new textbox named 'dear' is generated. So, if one clicks, say, 3 times the output is something like: dear dear dear
24
4394
by: RyanTaylor | last post by:
I have a final coming up later this week in my beginning Java class and my prof has decided to give us possible Javascript code we may have to write. Problem is, we didn't really cover JS and what we covered was within the last week of the class and all self taught. Our prof gave us an example of a Java method used to remove elements from an array: public void searchProcess() { int outIt=0;
18
2267
by: Vasileios Zografos | last post by:
Hello, can anyone please tell me if there is any difference between the two: double Array1; and
10
12213
by: | last post by:
I'm fairly new to ASP and must admit its proving a lot more unnecessarily complicated than the other languages I know. I feel this is because there aren't many good official resources out there to help do the most basic things. One of the "basic" things I haven't been able to find out how to do is how to delete an item from a multidimensional array object and resize it afterwards. It seems so easy to conceive of the code to delete...
29
4253
by: Jon Slaughter | last post by:
Is it safe to remove elements from an array that foreach is working on? (normally this is not the case but not sure in php) If so is there an efficient way to handle it? (I could add the indexes to a temp array and delete afterwards if necessary but since I'm actually working in a nested situation this could get a little messy. I guess I could set there values to null and remove them afterwards? Thanks, Jon
0
10153
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10007
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9946
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9832
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8830
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7371
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5272
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5413
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3921
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.