Forum Moderators: coopster

Message Too Old, No Replies

Comparing two arrays, replace values

         

martymac

9:02 pm on Sep 28, 2009 (gmt 0)

10+ Year Member



I have two arrays of data. The first array contains a list of URL's:

$itemID Array

0] => http://www.example.net/
1] => http://www.example.org/

The second array echoes two pieces of information. An ID that can range from 0 to 20, and another URL:

$itemURL Array

0 [example1.com...]
1 [science.example2.org...]
1 [example3.de...]
0 [example4.com...]
0 [example5.it...]
1 [example6.com...]

Im trying to figure out a way to replace the 1st value of the $itemURL array with the value of the matching key in the $itemID array. For example, the above would turn into:

http://www.example.net/ [example1.com...]
http://www.example.org/ [science.example2.org...]
http://www.example.org/ [example3.de...]
http://www.example.net/ [example4.com...]
http://www.example.net/ [iistsexample5it...]
http://www.example.org/ [example6.com...]

Ive tried a few things but nothing has worked and Im pretty much stumped. Thanks in advance for your help!

Here is the complete source code for the arrays:

$itemID = array ();
$itemURL = array ();

// ItemID Array
$xmlgz = gzopen('xml-files/analyseditem.xml.gz', 'r');
$contents = gzread($xmlgz, 10000);
$xml = simplexml_load_string($contents);
foreach ($xml->DataTables->DataTable->Row as $row) {
$pieces = explode("¦", $row);
$itemURL[] = ($pieces);
}

// Item URL Array
$file_handle = gzopen("xml-files/analyseditem.dat.gz", "r");
while (!feof($file_handle) ) {
$line_of_text = fgetcsv($file_handle, 1024);
if ($line_of_text[0] == "Header") {
continue;
}
echo $line_of_text[0] . $line_of_text[2] . "<br />";
}

[1][edited by: martymac at 9:44 pm (utc) on Sep. 28, 2009]

[edited by: dreamcatcher at 6:33 am (utc) on Sep. 29, 2009]
[edit reason] No Urls Please. See TOS. [/edit]

martymac

9:04 pm on Sep 28, 2009 (gmt 0)

10+ Year Member



I should note that this needs to be dynamic as the number of URLs on the $itemID array can go as high as 20.

andrewsmd

9:48 pm on Sep 28, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Since there are no actual arrays in php (all hash tables) you can just add them to a temp array and then replace your original array. Note: there is no need to replace the original array you could just use temp array if would like to keep all of your initial data.
<?php

$itemId = array("http://example.com", "http:example.net", "http://example.org");
$itemUrl = array("http://example2.com", "http:example2.net", "http://example2.org");
$tempArr = array();

foreach($itemId as $key => $i){

//if the key exists in the second array
if(array_key_exists($key, $itemUrl)){

//add the item to the new array
$tempArr[$i] = $itemUrl[$key];

}//if array_key_exists

}//foreach

//set the array
$itemUrl = $tempArr;

?>

Let me know if you have any questions.

martymac

5:50 am on Sep 30, 2009 (gmt 0)

10+ Year Member



ok thanks, ill give it a shot tomorrow.

martymac

5:29 pm on Sep 30, 2009 (gmt 0)

10+ Year Member



Thats not quite working for me. Let me explain what I need better:

$targetID Array
(
[0] => http://www.example.net/
=> http://www.example.org/
)

$itemURL Array
[5] => Array
(
[target-id] => 0
[url] => [example1.com...]
)

[6] => Array
(
[target-id] => 0
[url] => [science.example.org...]
)

[7] => Array
(
[target-id] => 0
[url] => [science.example.org...]
)

[8] => Array
(
[target-id] => 1
[2] => [example2.com...]

)

In the above $itemURL array, the value of 'target-id' should be replaced with the value of whatever key it matches in the $targetID array. All '0' should be
http://www.example.net' and all 1 should be 'http://www.example.org'

Any ideas?

[1][edited by: dreamcatcher at 7:02 pm (utc) on Sep. 30, 2009]
[edit reason] No Urls Please. See TOS. [/edit]

jd01

5:37 pm on Sep 30, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



for($i=0;$i<count($itemURL);$i++) {
foreach($targetID as $key => $val) {
if($itemURL[$i][target-id]==$key) { $itemURL[$i][url]=$val; }
}
}

Might get you close or give you some ideas.

andrewsmd

6:09 pm on Sep 30, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



So if I understand you correctly $itemUrl is a 2d array? If so then try this.
$targetID = Array( "0" => "http://www.example.net/", "1" => "http://www.example.org/");

$itemURL = Array("5" => Array("target-id" => "0", "url" => "http://www.example.com"),
"6" => Array("target-id" => "0", "url" => "http://science.example.org/article.pl?from=rss"),
"7" => Array("target-id" => "0", "url" => "http://science.example.org/article.pl?from=rss"),
"8" => Array("target-id" => "1", "url" => "http://www.example2.com"));

//go through the targetID array
foreach($targetID as $targetIdKey => $targetIdValue){

//start the double for on the intemURL
foreach($itemURL as $itemUrlKey => $tempArr){

//as long as your array structure never varies this
//will work otherwise it won't be cautious!
if(intval($tempArr['target-id']) == $targetIdKey){

//echo($targetIdValue);
$itemURL[$itemUrlKey]["target-id"] = $targetIdValue;

}//if

}//foreach $itemUrl

}//foreache $targetID

print_r($itemURL);

[edited by: dreamcatcher at 7:03 pm (utc) on Sep. 30, 2009]
[edit reason] No Urls Please. See TOS. [/edit]

martymac

6:44 pm on Sep 30, 2009 (gmt 0)

10+ Year Member



I tried using this:

for($i=0;$i<count($itemLines);$i++) {
foreach($itemID as $key => $val) {
if($itemLines[$i][0]==$key) {
$itemLines[$i][0]=$val; }
}

And this is much closer than before, however instead of replacing the entire value, it only changes once character. For example:

0 ¦ http://www.example.com

is changing to

h ¦ http://www.example.com

Thoughts?

[edited by: dreamcatcher at 7:04 pm (utc) on Sep. 30, 2009]
[edit reason] No Urls Please. See TOS. [/edit]

jd01

6:54 pm on Sep 30, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



for($i=0;$i<count($itemLines);$i++) {
foreach($itemID as $key => $val) {
if($itemLines[$i][0]==$key) {
$itemLines[$i][0]=$val; }
}

In this you are trying to check $itemLines[NUMBER][0] EG ($itemLines[1][0]) against the $key and if it matches, you are saying to change $itemLines[NUMBER][0] to = $key.

I think what you want is:
$itemLines[NUMBER]['target-id'] & $itemLines[NUMBER]['url']

Remember $i is just a counter, and you have an array of arrays, so what I posted loops through the array of arrays and checks against the single array.

I think the following should be correct: (If not, please post another example, because what you used does not match the example you posted. What I posted should work for what you posted.)

for($i=0;$i<count($itemLines);$i++) {
foreach($itemID as $key => $val) {
if($itemLines[$i]['target-id']==$key) {
$itemLines[$i]['url']=$val; }
}
} // Added this closing brace

I did forget quotes in my original tho... ['url'] & ['target-id'] Oops ;)

jd01

8:05 pm on Sep 30, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Let me give some more detail from the example you posted and I based the loops on:

/* Numerically you could use $itemLines[$i][0] & $itemLines[$i][1]. They are exactly the same as: $itemLines[$i]['target-id'] & $itemLines[$i]['url'] */

/* Loop through the array of arrays $itemLines */
for($i=0;$i<count($itemLines);$i++) {

/* split the $itemID array into a key / value pair and loop through the array */
foreach($itemID as $key => $val) {

/* compare the ['target-id'] (also $itemLines[$i][0]) of the current ($i = number) $itemLines[$i] array to the 'key' of each $itemID and if there is a match, set the current ['url'] (also $itemLines[$i][1]) to the 'value' of the $itemID key that matched, which is: $itemID[N]='url'. $key=N; $val='url'*/

if($itemLines[$i][0]==$key) { $itemLines[$i][1]=$val; }
}
}

andrewsmd

8:20 pm on Sep 30, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That's basically the same thing I wrote, only using numbers instead of the text keys and writing the if statement in one line. Both are correct, I just personally think that if you are using text keys, there usually is a reason so stick with the same convention. I also never write "one line" if statements because I think it makes it harder to debug later on. Just a personal preference though. Either one should work.

jd01

8:40 pm on Sep 30, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



<aside>
I used a for on the first one rather than 2 foreach loops, because a for is less processor intensive and faster. I would probably use two for's if I was writing it personally, but I thought the for followed by the foreach might be a bit easier to understand, because I think it's easier to follow the variables through.

As far as the the if goes I try to not use extra lines of code, and if you install YSlow and FireBug and run it on a site sometime and see how much you can compress a file just by eliminating 'white space', you'll probably understand why. If there is more than one action or statement or 'blah' following the if I spread it out, but otherwise it stays on one line and when I code comments are only allowed after braces for debugging... They come out when the script is finished and I usually single space indent lines.

But, like you said, those are all personal preference / coding style things.
</aside>

martymac

1:00 am on Oct 1, 2009 (gmt 0)

10+ Year Member



I would like to thank both of you gentlemen for your expertise. I re-examined my code and made adjustments.