applying array_unique - php

I have code to get the address which is separated by space and then fetching area details about that address so each time sql result is stored in array "resultArray" and that result is pushed to another array "returnArray" which is then displayed in the format of json.I want to remove duplicate area_id in returnArray so I used "array_unique" but it's not working .Please give some suggestion.
Sample Code:
<?php
include_once 'main.php';
$dac = new Main();
$add = $_POST['address'];
$noLines = sizeof($add);
$resultArray=array();
$returnArray=array();
$returnArrayMain=array();
while ($noLines>0)
{
$resultArray=array();
$result = $dac->area_detail($add[$noLines-1]);
$count=mysql_num_rows($result);
while($row = mysql_fetch_assoc($result))
{
$resultArray[]=array('area_id' => $row['area_id'],'area_name' => $row['area_name'],'area_GISlat'=>$row['area_GISlat'],'area_GISlon'=>$row['area_GISlon']);
}
array_push($returnArray, $resultArray) ;
$noLines = $noLines-1;
}
$returnArrayMain = array_unique($returnArray);
echo json_encode($returnArrayMain);
?>

Here is solution with a testing associative array:
// this is testing array as you are using:
$resultArray = array(
array(
'area_id' => 12,
'area_name' => 'test',
'area_GISlat'=>'test2',
'area_GISlon'=>'test3'),
array(
'area_id' => 11,
'area_name' => 'test',
'area_GISlat'=>'test2',
'area_GISlon'=>'test3'),
array(
'area_id' => 12,
'area_name' => 'test',
'area_GISlat'=>'test2',
'area_GISlon'=>'test3')
);
// take a temporary arry
$temporaryArr = array();
// initialize key's array
$arrayKey = array();
foreach ( $resultArray as $key => $values ) {
if ( !in_array($values, $temporaryArr) ) {
$temporaryArr[] = $values; // store values in temporary array
$arrayKey[$key] = true; // store all keys in another array
}
}
// now use array_intersect_key function for intersect both array.
$requiredArr = array_intersect_key($resultArray, $arrayKey);
echo "<pre>";
print_r($requiredArr);
Result:
Array
(
[0] => Array
(
[area_id] => 12
[area_name] => test
[area_GISlat] => test2
[area_GISlon] => test3
)
[1] => Array
(
[area_id] => 11
[area_name] => test
[area_GISlat] => test2
[area_GISlon] => test3
)
)
Removed duplicate arrays.
From PHP Manual:
array_intersect_key — Computes the intersection of arrays using keys for comparison
Side note:
Also add error reporting to the top of your file(s) right after your opening <?php tag
error_reporting(E_ALL);
ini_set('display_errors', 1);

try this
$returnArrayMain = array_map("unserialize", array_unique(array_map("serialize", $resultArray)));

try this..
$returnArrayMain = uniqueAssocArray($returnArray, 'area_id');
echo json_encode($returnArrayMain);
function uniqueAssocArray($array, $uniqueKey) {
if (!is_array($array)) {
return array();
}
$uniqueKeys = array();
foreach ($array as $key => $item) {
$groupBy=$item[$uniqueKey];
if (isset( $uniqueKeys[$groupBy]))
{
//compare $item with $uniqueKeys[$groupBy] and decide if you
//want to use the new item
$replace= ...
}
else
{
$replace=true;
}
if ($replace) $uniqueKeys[$groupBy] = $item;
}
return $uniqueKeys;
}

Related

How to show duplicate data in multidimensional array using PHP

I am using Spout Excel reader to read Excel files from php code and saving into a multidimensional array in PHP variable,Array looks like this
$array = [
[
'id[0]' => 'BX-78',
'Name[0]' => 'XXX',
'Address[0]' => 'YUUSATD'
],
[
'id[1]' => 'BX-79',
'Name[1]' => 'YYY',
'Address[1]' => 'DHJSHDJGY'
],
[
'id[2]' => 'BX-80',
'Name[2]' => 'ZZZ',
'Address[2]' => 'DDSDSDA'
]
[
'id[3]' => 'BX-78',
'Name[3]' => 'AAA',
'Address[3]' => 'FSDSDS'
][
'id[4]' => 'BX-81',
'Name[4]' => 'XXX',
'Address[4]' => 'DSDSDSD'
]];
Now i want to show duplicate data from above array using two keys ['id'] and ['name'] if id repeats show as duplicate data,
If name repeats show that row as duplicate data if both are duplicate show as again duplicate row
Otherwise it is unique row.
I have tried using multidimensional array sorting but it is using only one key to match data in rows.
foreach ($arrExcelData as $v) {
if (isset($arrExcelData[$v[0]])) {
// found duplicate
continue;
}
// remember unique item
$arrExcelData3[$v[0]] = $v;
}
// if you need a zero-based array, otheriwse work with $_data
$arrExcelData2 = array_values($arrExcelData3);
Edited : Expected Output Result :
Matching Rows:
Id Name Address
-------------------------
BX-78 XXX YUUSATD
BX-78 AAA DDSDSDA
BX-81 XXX DSDSDSD`
If you want to list the duplicate values, I think the address of the second match should be FSDSDS as there is not item with name AAA and value DDSDSDA:
BX-78 AAA FSDSDS
If that is the case, what you could do is to first use a double foreach to mark the arrays that contain a duplicate id or name by for example adding a property named id and name except when the array is itself in the second loop.
After this loop, you can tell which arrays are the duplicate ones. Instead of using a corresponding index 0 as in id[0], I have used reset and next so it is not tied to these indexes.
To get the filtered result you could use array_reduce to check for the array keys and unset them.
For example:
foreach ($array as $index => $a) {
foreach ($array as $v) {
if ($v === $a) continue;
if (reset($v) === reset($a)) $array[$index]["id"] = "duplicate";
if (next($v) === next($a)) $array[$index]["name"] = "duplicate";
}
}
$array = array_reduce($array, function($carry, $item) {
if (array_key_exists("id", $item) || array_key_exists("name", $item)) {
unset($item["id"], $item["name"]);
$carry[] = $item;
}
return $carry;
}, []);
print_r($array);
Result
Array
(
[0] => Array
(
[id[0]] => BX-78
[Name[0]] => XXX
[Address[0]] => YUUSATD
)
[1] => Array
(
[id[3]] => BX-78
[Name[3]] => AAA
[Address[3]] => FSDSDS
)
[2] => Array
(
[id[4]] => BX-81
[Name[4]] => XXX
[Address[4]] => DSDSDSD
)
)
See a php demo
I've this very pragmatic approach:
$spout_output = [
[
'id[0]' => 'BX-78',
'Name[0]' => 'XXX',
'Address[0]' => 'YUUSATD'
],
[
'id[1]' => 'BX-79',
'Name[1]' => 'YYY',
'Address[1]' => 'DHJSHDJGY'
],
[
'id[2]' => 'BX-80',
'Name[2]' => 'ZZZ',
'Address[2]' => 'DDSDSDA'
],
[
'id[3]' => 'BX-78',
'Name[3]' => 'AAA',
'Address[3]' => 'FSDSDS'
],
[
'id[4]' => 'BX-81',
'Name[4]' => 'XXX',
'Address[4]' => 'DSDSDSD'
]];
// store id to row, and name to row mappings.
// id and name will be keys, value will be an array of indexes of the array $spout_output
$id_to_rows = array();
$name_to_rows = array();
$duplicate_ids = array();
$duplicate_names = array();
foreach($spout_output as $row => $data)
{
$key_id = 'id['.$row.']';
$key_name = 'Name['.$row.']';
if(!isset($data[$key_id]))
continue;
$value_id = $data[$key_id];
$value_name = $data[$key_name];
if(!isset($id_to_rows[$value_id]))
{
$id_to_rows[$value_id] = array();
}
else
{
if(!isset($duplicate_ids[$value_id]))
{
$duplicate_ids[$value_id] = $id_to_rows[$value_id];
}
$duplicate_ids[$value_id][] = $row;
}
if(!isset($name_to_rows[$value_name]))
{
$name_to_rows[$value_name] = array();
}
else
{
if(!isset($duplicate_names[$value_name]))
{
$duplicate_names[$value_name] = $name_to_rows[$value_name];
}
$duplicate_names[$value_name][] = $row;
}
$id_to_rows[$value_id][] = $row;
$name_to_rows[$value_name][] = $row;
}
echo 'Duplicates:';
echo '<br>';
$shown_rows = array();
foreach($duplicate_ids as $id => $rows)
{
foreach($rows as $nr)
{
echo $id . '|' . $spout_output[$nr]['Name['.$nr.']'] . '|' . $spout_output[$nr]['Address['.$nr.']'];
echo '<br>';
$shown_rows[] = $nr;
}
}
foreach($duplicate_names as $name => $rows)
{
foreach($rows as $nr)
{
// if already shown above, skip this row
if(in_array($nr, $shown_rows))
continue;
echo $spout_output[$nr]['id['.$nr.']'] . '|' . $spout_output[$nr]['Name['.$nr.']'] . '|' . $spout_output[$nr]['Address['.$nr.']'];
echo '<br>';
$shown_rows[] = $nr;
}
}
Outputs:
Duplicates:
BX-78|XXX|YUUSATD
BX-78|AAA|FSDSDS
BX-81|XXX|DSDSDSD
I think your 'wanted output' contains an error in the address?
Anyway, with my code above I think you'll have enough mapped data to produce the output you want.
You could do something like this:
$dupes = [];
$current = [];
foreach ($array as $index => $entry) {
$idKey = "id[$index]";
$nameKey = "Name[$index]";
if (array_key_exists($entry[$idKey], $current)) {
$dupes[] = [$entry, $current[$entry[$idKey]]];
}
elseif (array_key_exists($entry[$nameKey], $current)) {
$dupes[] = [$entry, $current[$entry[$nameKey]]];
}
else {
$current[$entry[$idKey]] = $current[$entry[$nameKey]] = $entry;
}
}
print_r($dupes);
Which results in an array containing each set of duplicates (array of arrays):
Array
(
[0] => Array
(
[0] => Array
(
[id[3]] => BX-78
[Name[3]] => AAA
[Address[3]] => FSDSDS
)
[1] => Array
(
[id[0]] => BX-78
[Name[0]] => XXX
[Address[0]] => YUUSATD
)
)
[1] => Array
(
[0] => Array
(
[id[4]] => BX-81
[Name[4]] => XXX
[Address[4]] => DSDSDSD
)
[1] => Array
(
[id[0]] => BX-78
[Name[0]] => XXX
[Address[0]] => YUUSATD
)
)
)
Demo here: https://3v4l.org/JAtNU
In case someone of you are searching unique values by key.
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
This function just takes multidimensional array and key value of field you need.
Then takes value of given array one by one (smaller arrays).
Then traverses given array and looking if taken key-value pair matches with given key.
After that if taken key-value pair matches with given key function just inserts smaller array in temporary array (array with unique values).
Don't forget to increment indexes of arrays ($i).
Then return array you got (with unique values) after function ends work.

error while appending data into an array using array_push in php

I want to filter my data_array and create a new array $arr with new data.I tried using following function.it is not appending data. but it is replacing the data.I know that I have to use array_push(). when I did that data is appending to the array as single elements.
foreach ($data_array as $value) {
try {
$rep = $value->rep;
$idposition_rep = $value->idposition_rep;
$max_idinvoice = $value->max_idinvoice;
$idsession = $value->idsession;
$i_date = $value->i_date;
$last_i_time_string = $value->last_i_time;
$delayTime = $value->delayTime;
if ($delayTime > 30) {
$arr[] = array(
'rep' => $rep,
'idposition_rep' => $idposition_rep,
'max_idinvoice' => $max_idinvoice,
'idsession' => $idsession,
'i_date' => $i_date,
'last_i_time_string' => $last_i_time_string,
'curr_time' => date("H:i:s"),
'delayTime' => $delayTime);
}
} catch (PDOException $ex) {
echo $ex->getMessage();
die;
}
}
I had created sample code based on your requirement. replace as per your requirement with variables and assignment.
$data_array is sample input array.
$data_array = array('1' => 'abc', '2'=>'das', '3' => 'def');
$arr = array();
$i=0;
foreach ($data_array as $value) {
try {
$rep = $value;
$aval = strpos($rep,'a'); // Put Your condition for display Time > 30
if ($aval !== false) {
$arr[$i] = array(
'rep' => $rep // assign values get from input array.
);
$i++;
}
} catch (PDOException $ex) {
echo $ex->getMessage();
die;
} }
print_r($arr);
OUTPUT:
Array
(
[0] => Array
(
[rep] => abc
)
[1] => Array
(
[rep] => das
)
)
Hope this will help you.

PHP Remove Multidimensional Array Value

I have array multidimensional code like this:
$array = [
'fruits' => ['apple','orange','grape', 'pineaple'],
'vegetables' => ['tomato', 'potato']
];
$eaten = 'grape';
unset($array[$eaten]);
and what i need is to delete 'grape' from the array because 'grape' already eaten. how to fix my code to unset the 'grape'?
and my question number two, if it can be unset, is there a way to unset multi value like
unset($array,['grape','orange']);
thanks for help..
You can remove eaten element by following way. Use array_search() you can find key at the position of your eaten element.
Here below code shows that in any multidimensional array you can call given function.
$array = [
'fruits' => ['apple','orange','grape', 'pineaple'],
'vegetables' => ['tomato', 'potato']
];
$eaten = 'grape';
$array = removeElement($array, $eaten);
function removeElement($data_arr, $eaten)
{
foreach($data_arr as $k => $single)
{
if (count($single) != count($single, COUNT_RECURSIVE))
{
$data_arr[$k] = removeElement($single, $eaten);
}
else
{
if(($key = array_search($eaten, $single)) !== false)
{
unset($data_arr[$k][$key]);
}
}
}
return $data_arr;
}
P.S. Please note that you can unset() multiple elements in single call. But the way you are using unset is wrong.
Instead of using unset() i suggest you to create a new Array after removal of required value benefit is that, your original array will remain same, you can use it further:
Example:
// your array
$yourArr = array(
'fruits'=>array('apple','orange','grape', 'pineaple'),
'vegetables'=>array('tomato', 'potato')
);
// remove array that you need
$removeArr = array('grape','tomato');
$newArr = array();
foreach ($yourArr as $key => $value) {
foreach ($value as $finalVal) {
if(!in_array($finalVal, $removeArr)){ // check if available in removal array
$newArr[$key][] = $finalVal;
}
}
}
echo "<pre>";
print_r($newArr);
Result:
Array
(
[fruits] => Array
(
[0] => apple
[1] => orange
[2] => pineaple
)
[vegetables] => Array
(
[0] => potato
)
)
Explanation:
Using this array array('grape','tomato'); which will remove the value that you define in this array.
This is how I would do it.
$array = [
'fruits' => ['apple','orange','grape', 'pineaple'],
'vegetables' => ['tomato', 'potato']
];
$unset_item = 'grape';
$array = array_map(function($items) use ($unset_item) {
$found = array_search($unset_item, $items);
if($found){
unset($items[$found]);
}
return $items;
}, $array);

PHP Find a value in a key and get the value of another key in a multi-dimentional array

Might be a newbie question but I've been trying to figure this problem and it's doing my head in.
I have the following array :
[0] => Array
(
[provisionalBookingRoomID] => 1
[totalSpecificRoomCount] => 2
)
[1] => Array
(
[provisionalBookingRoomID] => 2
[totalSpecificRoomCount] => 5
)
I need a php function that searches through the array for the value of 'provisionalBookingRoomID' and returns the value of 'totalSpecificRoomCount'
basically something like the following
getProvisionalTotalRoomsCount($currentRoom, $arrayOfRooms);
// getProvisionalTotalRoomsCount('1', $arrayOfRooms) should return 2;
Any ideas?
Check this:
getProvisionalTotalRoomsCount($currentRoom, $arrayOfRooms){
foreach($arrayOfRooms as $key=>$value){
if($value['provisionalBookingRoomID'] == $currentRoom){
return $value['totalSpecificRoomCount'];
}
}
}
For anyone looking for a generic function :
function findValueInArray($array, $searchValue, $searchKey, $requiredKeyValue) {
foreach($array as $key=>$value){
if($value[$searchKey] == $searchValue){
return $value[$requiredKeyValue];
}
}
}
// Usage : findValueInArray($provisionalBookedRoomsArray, '1', 'provisionalBookingRoomID', 'totalSpecificRoomCount');
If you are likely to work with more than one value, you could build a new array with a 1->1 map for those attributes.
<?php
$items = array(
array(
'name' => 'Foo',
'age' => 23
),
array(
'name' => 'Bar',
'age' => 47
)
);
// Php 7
$name_ages = array_column($items, 'name', 'age');
echo $name_ages['Foo']; // Output 23
// Earlier versions:
$name_ages = array();
foreach($items as $value)
{
$name_ages[$value['name']] = $value['age'];
}
echo $name_ages['Foo']; // Output 23
$value = 0;
$array = array(array("provisionalBookingRoomID"=>1,"totalSpecificRoomCount"=>2),array("provisionalBookingRoomID"=>2,"totalSpecificRoomCount"=>5));
array_map(
function($arr) use (&$value) {
if($arr['provisionalBookingRoomID']==1) {
$value = $arr['totalSpecificRoomCount'];
}
},$array
);
echo $value;

Build multidimensional array from an array in PHP

I would like to build a multidimensional array from an array. For example I would like
$test = array (
0 => 'Tree',
1 => 'Trunk',
2 => 'Branch',
3 => 'Limb',
4 => 'Apple',
5 => 'Seed'
);
to become
$test =
array (
'Tree' => array (
'Trunk' => array (
'Branch' => array (
'Limb' => array (
'Apple' => array (
'Seed' => array ()
)
)
)
)
)
);
or more simply
$result[Tree][Trunk][Branch][Limb][Apple][Seed] = null;
I'm trying to do this with a recursive function but i'm hitting memory limit so I'm clearly doing it wrong.
<?php
$test = array (
0 => 'Tree',
1 => 'Trunk',
2 => 'Branch',
3 => 'Limb',
4 => 'Apple',
5 => 'Seed'
);
print_r($test);
print "results of function";
print_r(buildArray($test));
function buildArray (&$array, &$build = null)
{
if (count($array) > 0)
{
//create an array, pass the array to itself removing the first value
$temp = array_values($array);
unset ($temp[0]);
$build[$array[0]] = $temp;
buildArray($build,$temp);
return $build;
}
return $build;
}
Here's an approach with foreach and without recursion, which works:
function buildArray($array)
{
$new = array();
$current = &$new;
foreach($array as $key => $value)
{
$current[$value] = array();
$current = &$current[$value];
}
return $new;
}
[ Demo ]
Now your function... first, using $build[$array[0]] without defining it as an array first produces an E_NOTICE.
Second, your function is going into infinite recursion because you are not actually modifying $array ($temp isn't the same), so count($array) > 0 will be true for all of eternity.
And even if you were modifying $array, you couldn't use $array[0] anymore, because you unset that, and the indices don't just slide up. You would need array_shift for that.
After that, you pass $build and $temp to your function, which results in further because you now you assign $build to $temp, therefore creating another loop in your already-infinitely-recurring loop.
I was trying to fix all of the above in your code, but eventually realized that my code was now pretty much exactly the one from Pevara's answer, just with different variable names, so... that's that.
This function works recursively and does the trick:
function buildArray($from, $to = []) {
if (empty($from)) { return null; }
$to[array_shift($from)] = buildArray($from, $to);
return $to;
}
In your code I would expect you see an error. You are talking to $build in your first iteration as if it where an array, while you have defaulted it to null.
It seems to be easy
$res = array();
$i = count($test);
while ($i)
$res = array($test[--$i] => $res);
var_export($res);
return
array ( 'Tree' => array ( 'Trunk' => array ( 'Branch' => array ( 'Limb' => array ( 'Apple' => array ( 'Seed' => array ( ), ), ), ), ), ), )
Using a pointer, keep re-pointing it deeper. Your two output examples gave array() and null for the deepest value; this gives array() but if you want null, replace $p[$value] = array(); with $p[$value] = $test ? array() : null;
$test = array(
'Tree',
'Trunk',
'Branch',
'Limb',
'Apple',
'Seed'
);
$output = array();
$p = &$output;
while ($test) {
$value = array_shift($test);
$p[$value] = array();
$p = &$p[$value];
}
print_r($output);

Categories