Forum Moderators: coopster

Message Too Old, No Replies

Compare array values and replace when it is similar

compare array values

         

iyappan

5:55 am on Apr 13, 2010 (gmt 0)

10+ Year Member



I have an array of data like:

Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ12345
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ12345
)


[2] => Array
(
[d_id] => 634
[i_id] => 638
[m_number] => 20016
[d_number] => AEQ12345
)

)

In the above array I have to check for the value "d_number" in the array and if it repeats I have to increment the value of the matching element and the final array should look like this:

Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ12345
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ12346 //Changed value
)


[2] => Array
(
[d_id] => 634
[i_id] => 638
[m_number] => 20016
[d_number] => AEQ12347 //Changed value
)

)

Any help on this?

Readie

11:46 am on Apr 13, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Welcome to Webmaster World iyappan.

Ok, your full array is $someArray.

$count = count($someArray);
$rows = ($count - 1);

for($i = 0; $i < $rows; $i++) {
preg_match('/^([^\d]*)([\d]+)$/', $someArray[$i]['d_number'], $out[$i]);
for($n = 0; $n < $i; $n++) {
preg_match('/^[^\d]*([\d]+)$/', $someArray[$n]['d_number'], $check);
if($out[$i][2] == $check[1]) {
$out[$i][2] += 1;
}
}
$someArray[$i]['d_number'] = $out[$i][1] . $out[$i][2];
}

I think that'll work...

iyappan

12:39 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



Thanks for the reply Readie,

I tried with the functionality you sent but it returned the array of last values like:

Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ12346
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ12347
)


[2] => Array
(
[d_id] => 634
[i_id] => 638
[m_number] => 20016
[d_number] => AEQ12347
)

)

Readie

1:17 pm on Apr 13, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I think I know what happened there.

$count = count($someArray);

for($i = 0; $i < $count; $i++) {
preg_match('/^([^\d]*)([\d]+)$/', $someArray[$i]['d_number'], $out[$i]);
if($i > 0) {
for($n = 0; $n < $i; $n++) {
preg_match('/^[^\d]*([\d]+)$/', $someArray[$n]['d_number'], $check);
if($out[$i][2] == $check[1]) {
$out[$i][2] += 1;
}
}
}
$someArray[$i]['d_number'] = $out[$i][1] . $out[$i][2];
}

No idea why I took 1 away from $count :/ I think I must have changed my mind partway through.

iyappan

3:47 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



Thanks Readie. It works great. Also I have other problem with the array. If the array is like:(not continuously positioned). Here the array start from '2'.


Array
(
[2] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ12345
)

[4] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ12345
)


[6] => Array
(
[d_id] => 634
[i_id] => 638
[m_number] => 20016
[d_number] => AEQ12345
)

)

Can I make a foreach loop for this?

Thanks again for the reply and help.

Readie

3:59 pm on Apr 13, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Umm, Yes, though that's going to a bit more difficult.

Try this:

$i = 0;
foreach($someArray as $current) {
preg_match('/^([^\d]*)([\d]+)$/', $current['d_number'], $out[$i]);
if(isset($prev)) {
foreach($prev as $pre) {
preg_match('/^[^\d]*([\d]+)$/', $pre, $check);
if($out[$i][2] == $check[1]) {
$out[$i][2] += 1;
} // if
} // foreach
} // if
$prev[$i] = $out[$i][2];
$current['d_number'] = $out[$i][1] . $out[$i][2];
$i += 1;
} // foreach

iyappan

4:25 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



Apart from the above solution I tried to sort the array which renumbers the array and works fine. I will try the suggested one by you and reply tommorow.

Thanks for the help.

iyappan

9:25 am on Apr 14, 2010 (gmt 0)

10+ Year Member



Thanks Readie. I have other array like this:

Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ12345
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ12345
)


[2] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12345
)


[3] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12345
)

)

and the result array should be

Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ12345
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ12346 //Changed value
)


[2] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12345
)


[3] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12346 //changed value
)

)


Any ideas on this. Thanks again for the great help.

Readie

12:13 pm on Apr 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yep, very easy to modify the previous code.

$i = 0;
foreach($someArray as $current) {
preg_match('/^([^\d]*)([\d]+)$/', $current['d_number'], $out[$i]);
if(isset($prev)) {
preg_match('/^[^\d]*([\d]+)$/', $prev, $check);
if($out[$i][2] == $check[1]) {
$out[$i][2] += 1;
} // if
} // if
$prev = $out[$i][2];
$current['d_number'] = $out[$i][1] . $out[$i][2];
$i += 1;
} // foreach

iyappan

7:11 am on Apr 16, 2010 (gmt 0)

10+ Year Member



Hi Readie,

Thanks for the help. Other quick question based on the previous one.


Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ
)


[2] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN
)


[3] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN
)

)


I have the array as defined above and need to check the d_number with the database and if the value exists in the database it will return the max value and it will be assigned to the next occurence, but if not exists then it will assigned the 12345.

scenario will be if the AEQ is found and the max value is returned from the db as 12347 it will assign the AEQ value as AEQ12348 and AEQ12349.
If the value is not found for AEN it will assign from first value like AEN12345 and AEN12346.


Currently I am checking the exisiting values from table in a seperate loop, but I wanted this to happen in a single loop.


The final output for the above defined scenario will be:


Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ12348
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ12349
)


[2] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12345
)


[3] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12346
)

)

Thanks again for your help.

Readie

2:17 pm on Apr 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In the database, is is set up as:

COL1 | COL2
AEN | 12345
AEQ | 12345

Or some other way?

iyappan

2:22 pm on Apr 16, 2010 (gmt 0)

10+ Year Member



In the database the setup is like
It is stored in the single field.

col1
AEN12345
AEQ12345

Readie

2:27 pm on Apr 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hmm, annoying... Is it just those 2 values, or every single d_number currently in use under that column?

iyappan

2:31 pm on Apr 16, 2010 (gmt 0)

10+ Year Member



It is every single d_number currently in use under that column. sorry for the miscommunication

Readie

2:40 pm on Apr 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Right, so as we increase the numbers, we need to insert new values into the database too.

First, I need you to test something though, as this will affect the method I use here.

$sql = 'SELECT d_number FROM table WHERE d_number LIKE "AEQ%" ORDER BY d_number DESC';
$result = mysql_query($sql);
echo mysql_result($result, 0, "d_number");
$sql = 'SELECT d_number FROM table WHERE d_number LIKE "AEN%" ORDER BY d_number DESC';
$result = mysql_query($sql);
echo mysql_result($result, 0, "d_number");

Does that output the highest 2 numbers? I'm not 100% certain how MySQL treats sorting for alphanumeric strings.

iyappan

3:01 pm on Apr 16, 2010 (gmt 0)

10+ Year Member



Ok. Here is the complete scenario.

Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ
)


[2] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN
)


[3] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN
)

)


The above is the array returned by the form.

In the table the value of d_number is stored like

d_number
AEN12345
AEQ12345
AES12345
AEX12345
..
...
..
..
..

Now I am getting the maximum value from the table matching the form value like

$query = "SELECT MAX(d_number) FROM tbl_name WHERE d_number LIKE 'AEN%';

The above query returns the maximum value of d_number present in the table. In the above case it returns AEN12345. Similarly the form values are looped in the table and maximum value is found for all the values in the array.

If the form value matches the database value then the form value is incremented with the databasematched value+1 or the the form value is assigned to formvalue+12345.

I hope this will give u a better idea.

Readie

3:22 pm on Apr 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Ahh, I see.

Right then, let's try the following:

foreach($someArray as $stuff) {
if(!isset($check[$stuff['d_number']])) {
$sql = 'SELECT MAX(d_number) FROM table WHERE d_number LIKE "' . mysql_real_escape_string($stuff['d_number']) . '%"';
preg_match('/^[^\d]+([\d]+)$/', mysql_result(mysql_query($sql), 0, "d_number"), $out);
$check[$stuff['d_number']] = $out[1];
}
$check[$stuff['d_number']] += 1;
$stuff['d_number'] .= $check[$stuff['d_number']];
}

iyappan

3:26 pm on Apr 16, 2010 (gmt 0)

10+ Year Member



Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ
)


[2] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN
)


[3] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN
)

)


In the above array I loop the above value with the table in the below format

foreach($majos as $pos =>$majo):
$prefixcode = [$pos][d_number];
$dnrfprefix = "SELECT MAX((d_number) FROM prefixes WHERE d_number LIKE 'AEN%'";
if(substr($dnrfprefix[0]['dnrf'], 0, -5) != $prefixcode)
{
[$pos]['d_number']= $prefixcode.'12345';

}else{
[$pos]['d_number'] = $prefixcode.(substr($dnrfprefix[0]['dnrf'], -5,5)+1);
}
endforeach;



The above loop checks for the value in the existing table and if it is available then it adds one to the existing value or assign the 12345 at the last along with the existing d_number from the form and returns the array in the following format.

Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ12345
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ12345
)


[2] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12347 // Assuming that there is an matching value existing for AEN with AEN12346 in the table.
)


[3] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12347
)

)


Then I introduce the loop you suggested and returns the array like:

$rows = ($count - 1);

for($i = 0; $i < $count; $i++) {
preg_match('/^([^\d]*)([\d]+)$/', $this->data['dnrf_prefixes'][$i]['dnrf_number'], $out[$i]);
for($n = 0; $n < $i; $n++) {
preg_match('/^[^\d]*([\d]+)$/', $this->data['dnrf_prefixes'][$n]['dnrf_number'], $check);
if($out[$i][0] == $check[0]) {
$out[$i][2] += 1;
}
}
$this->data['dnrf_prefixes'][$i]['dnrf_number'] = $out[$i][1] . $out[$i][2];
}





Array
(
[0] => Array
(
[d_id] => 634
[i_id] => 613
[m_number] => 20016
[d_number] => AEQ12345
)

[1] => Array
(
[d_id] => 634
[i_id] => 1069
[m_number] => 20016
[d_number] => AEQ12346
)


[2] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12347 // Assuming that there is an matching value existing for AEN with AEN12346 in the table.
)


[3] => Array
(
[d_id] => 635
[i_id] => 638
[m_number] => 20016
[d_number] => AEN12348
)

)


This is the whole process. Instead of this many loops can we complete the above logic in a single loop.

Readie

3:27 pm on Apr 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



See my post above :)

iyappan

3:43 pm on Apr 16, 2010 (gmt 0)

10+ Year Member



The above logic returns the blank value. But the query is returning the correct value.

Readie

3:48 pm on Apr 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Is the problem here where there is no value in the database? This occured to me a few minutes before you posted. Try this if that's the case:

foreach($someArray as $stuff) {
if(!isset($check[$stuff['d_number']])) {
$sql = 'SELECT MAX(d_number) FROM table WHERE d_number LIKE "' . mysql_real_escape_string($stuff['d_number']) . '%"';
$result = mysql_query($sql);
if(mysql_fetch_array($result)) {
preg_match('/^[^\d]+([\d]+)$/', mysql_result($result, 0, "d_number"), $out);
$check[$stuff['d_number']] = $out[1];
} else {
$check[$stuff['d_number']] = 12345;
}
}
$check[$stuff['d_number']] += 1;
$stuff['d_number'] .= $check[$stuff['d_number']];
}

iyappan

3:52 pm on Apr 16, 2010 (gmt 0)

10+ Year Member



Sorry. I will try and updated tommorow since I have to leave office now and travel.

Thanks again for the help.

Also can u share me with your personal mail id?

Readie

4:03 pm on Apr 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Umm, I'm a bit unhappy with the idea of sharing my personal E-mail with people I don't really know. I get an E-mail alert whenever I receive a message via these forum's StickyMail system though, so you can gaurantee I'll get the message if you use that.

nickCR

4:35 pm on Apr 16, 2010 (gmt 0)

10+ Year Member



I would like to offer some help here.

First what will you be using this modified number for? Is it just to change the number and then update the database with the modified number?

Readie has provided some good advice but i'm a little concerned with this because I sense that you might have some problems with scaling.

If you are trying to get the results from the database to then update the database then here is what I would suggest:

1. Select a count with a group on the d_number field (this will tell you which numbers are duplicated).

2. Foreach result with a count > 1 then you want to:

- select all the records from the database with the current d_number (this will give you a result of all the records that have this d_number)

- select that d_number from the database using the first 3 characters of the d_number and sort by d_number desc. (this will give you the last number for that series in the database).

- create a foreach to go through each record, your starting number will be the last one returned from the previous query then just update and increase the counter by one for each.

This is assuming that you are running this in a process that will be updating the database each night or something of such.

I think both options are good under those conditions but running this process everytime the page loads would be quite a bit of overhead.

iyappan

5:21 am on Apr 17, 2010 (gmt 0)

10+ Year Member



Thanks for the suggestion NickCR.

The concept suggested by you is more or less similar to what I expect.
You can understand my situation form the above queries I hope. Let me explain in detail.


1. When a user submits the form multidimensional array is created with sequence of "d_number" with only the first three values like "AEF", "AEQ", "AEN" ......

2. The above "d_number" will be stored in the table with the number added to it. If the values are not found in the table from the array it will be assigned as AEF12345, AEQ12345, AEN12345.

3. But if the value is found For Ex. if the max value found for AEF is AEF12347 then the AEF will be assigned as AEF12348.

4. Again for multiple instance of AEF a number will be added like AEF12349, AEF12350 ....

5. I hope that there is no necessity of selecting all records from the table, will it not be fine to select the maximum value of the corresponding three digit value?.

Since I am totally confused with the logic can u please suggest me a logic.


Thanks for the help.

iyappan

6:51 am on Apr 17, 2010 (gmt 0)

10+ Year Member



Readie, I tried the new logic but still returning the blank value.

Readie

10:29 am on Apr 17, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hmm, I was a bit uncertain about the syntax of $check[$stuff['d_number']]

Try this:

foreach($someArray as $stuff) {
$ident = $stuff['d_number'];
if(!isset($check[$ident])) {
$sql = 'SELECT MAX(d_number) FROM table WHERE d_number LIKE "' . mysql_real_escape_string($ident) . '%"';
$result = mysql_query($sql);
if(mysql_fetch_array($result)) {
preg_match('/^[^\d]+([\d]+)$/', mysql_result($result, 0, "d_number"), $out);
$check[$ident] = $out[1];
} else {
$check[$ident] = 12345;
}
}
$check[$ident] += 1;
$stuff['d_number'] .= $check[$ident];
}

iyappan

12:57 pm on Apr 20, 2010 (gmt 0)

10+ Year Member



Hi Readie,

Thanks for the help.

$i = 0;
foreach($someArray as $current) {
preg_match('/^([^\d]*)([\d]+)$/', $current['d_number'], $out[$i]);
if(isset($prev)) {
foreach($prev as $pre) {
preg_match('/^[^\d]*([\d]+)$/', $pre, $check);
if($out[$i][2] == $check[1]) {
$out[$i][2] += 1;
} // if
} // foreach
} // if
$prev[$i] = $out[$i][2];
$current['d_number'] = $out[$i][1] . $out[$i][2];
$i += 1;
} // foreach


In the above logic it replace the value only for the first two.

if the array is like


YTE12345
YTE12345
YTE12345
YTE12345


it replaces like
YTE12345
YTE12346
YTE12345
YTE12345


Any suggestions for this.

Readie

1:07 pm on Apr 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



foreach($someArray as $current) {
preg_match('/^([^\d]*)([\d]+)$/', $current['d_number'], $out);
if(isset($prev)) {
$prev += 1;
} else {
$prev = $out[2];
}
$current['d_number'] = $out[1] . $prev;
}

iyappan

4:11 pm on Apr 20, 2010 (gmt 0)

10+ Year Member



The problem with the above logic is
If the array is like
YTE12345
YTE12345
YTE12345
YTE12345

It replaces fine like

YTE12345
YTE12346
YTE12347
YTE12348

But if the array is

YTE12345
YTE12345
YTE12345
YTB12345
YTB12345
YTS12345
YTS12345


the result array is


YTE12345
YTE12346
YTE12347
YTB12348
YTB12349
YTS12350
YTS12351

Please note the fourth value is changed from YTE to YTB.

Thanks for the reply
This 32 message thread spans 2 pages: 32