PHP Unique MultiDimensional Array Issue - php

So, I am getting unique values from my MD array utilizing the following function:
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;
}
My array is similar to the following:
Array (
[0] =>
Array (
'name' => 'Nevada'
)
[1] =>
Array (
'name' => 'Colorado'
)
[2] =>
Array (
'name' => 'Nevada'
)
[3] =>
Array (
'name' => 'Colorado'
)
[4] =>
Array (
'name' => 'Oklahoma'
)
[5] =>
Array (
'name' => 'Nevada'
)
[6] =>
Array (
'name' => 'Nevada'
)
)
And using the function (unique_multidim_array ( $term_arr, 'name' )) above I am getting a single Nevada and a single Colorado, however, it is not returning Oklahoma
What can I do to ensure that it will return unique values, even if there are no duplicates?

Your resulting array keeps the original indices, and, depending on how you are iterating over it, you might get unexpected results. Try resetting the indices:
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[] = $val; // <--- remove the $i
}
$i++;
}
return $temp_array;
}
Or, as you say, array_values() will help too:
$term_arr = array_values ( unique_multidim_array ( $term_arr, 'name' ) );

PHP already has a function to remove duplicates from an array
array_unique(array)
should do the trick

Related

PHP convert multiple strings with special chars as delimiters to array

I have a multiple arrays with strings that comes out from a wordpress database.
Its a table from a plugin that stores the data in a very strange way, like this:
print_r($results);
Array
(
[form] => text^name14^Antony~text^secondname14^White~email^email14^antony.white#gmail.com
)
Array
(
[form] => ......
)
I need to get the clean data, so:
foreach ($results as $result) {
$formdata_array = explode('~',$result);
$formdata_array_count = count($formdata_array);
for ( $i=0 ; $i < $formdata_array_count ; $i++) {
if ( empty( $formdata_array[$i] ) ) {
continue;
}
$elemnts = explode('^',$formdata_array[$i]);
$type = $elemnts[0];
$element_name = $elemnts[1];
$value = $elemnts[2];
$value = nl2br($value);
}
And at this point I get:
print_r($value)
Antony
White
antony.white#gmail.com
But I need to have an array to work with
Array
(
[0] => Antony
[1] => White
[2] => antony.white#gmail.com
)
I triede differents methods like array_merge, array_column, array_combine but I can't get the final result
This probably is what you are looking for:
<?php
$results = [
['form' => "text^name14^Antony~text^secondname14^White~email^email14^antony.white#gmail.com"],
['form' => "text^name14^Georgy~text^secondname14^Black~email^email14^georgy.black#gmail.com"],
];
foreach ($results as $result) {
$output = [];
$formdata_array = explode('~',$result['form']);
$formdata_array_count = count($formdata_array);
for ( $i=0 ; $i < $formdata_array_count ; $i++) {
if ( empty( $formdata_array[$i] ) ) {
continue;
}
$elements = explode('^',$formdata_array[$i]);
$output[] = [
'type' => $elements[0],
'name' => $elements[1],
'value' => $elements[2],
];
}
print_r(array_column($output, 'value'));
}
The output is:
Array
(
[0] => Antony
[1] => White
[2] => antony.white#gmail.com
)
Array
(
[0] => Georgy
[1] => Black
[2] => georgy.black#gmail.com
)

Don't want Array ito combine values

I Have an array in PHP that looks like:
Array ( [2099:360] => 6-3.25 [2130:361] => 4-2.5 [2099:362] => 14-8.75 )
Notice there is Two Keys that are 2099 and one that is 2130. I Have a foreach to remove the everything after the colon. the $drop is my array
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
$a[$ex_part[0]] = $drop_a;
}
print_r($a);
but when I print $a it displays only the recent value of the 2099?
Array ( [2099] => 14-8.75 [2130] => 4-2.5 )
Any Successions? How can I get it to display all of the values?
Thank You for Your Help
One solution is to use a multi-dimensional array to store this strategy:
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
if (isset($a[$ex_part[0]])) {
$a[$ex_part[0]][] = $drop_a;
} else {
$a[$ex_part[0]] = array($drop_a);
}
}
Your resulting data-set will however be different:
Array ( [2099] => Array ( [0] => 6-3.25 [1] => 14-8.75) [2130] => Array ( [0] => 4-2.5 ) )
It may be beneficial to you to preserve the second portion after the colon :
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
if (isset($a[$ex_part[0]])) {
$a[$ex_part[0]][$ex_part[1]] = $drop_a;
} else {
$a[$ex_part[0]] = array($ex_part[1] => $drop_a);
}
}
Now your result is a little more meaningful:
Array ( [2099] => Array ( [360] => 6-3.25 [362] => 14-8.75) [2130] => Array ( [361] => 4-2.5 ) )
Finally you can use alternative key-naming strategy if one is already occupied:
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
if (isset($a[$ex_part[0]])) {
$a[altName($ex_part[0], $a)] = $drop_a;
} else {
$a[$ex_part[0]] = $drop_a;
}
}
function altName($key, $array) {
$key++; // Or however you want to do an alternative naming strategy
if (isset($array[$key])) {
return altName($key, $array); // This will eventually resolve - but be careful with the recursion
}
return $key;
}
Returns:
Array
(
[2099] => 6-3.25
[2130] => 4-2.5
[2100] => 14-8.75
)
You basically have a key and a sub key for each entry, so just put them in a multidimensional array:
$a = array();
foreach ($drop as $key => $val) {
list($key, $subKey) = explode(':', $key);
$a[$key][$subKey] = $val;
}
Gives you:
Array
(
[2099] => Array
(
[360] => 6-3.25
[362] => 14-8.75
)
[2130] => Array
(
[361] => 4-2.5
)
)
You can traverse multidimensional arrays by nesting loops:
foreach ($a as $key => $subKeys) {
foreach ($subKeys as $subKey => $val) {
echo "$key contains $subKey (value of $val) <br>";
}
}

Convert Multi dimensional array PHP

I want to convert multi dimensional array in Php
I'm stuck in logic.. Kindly help
Thanks in advance
Current Produced array :
Array
(
[5316] => Array
(
[0] => Array
(
[PROD1] => color=black
)
[1] => Array
(
[PROD1] => paper=a1
)
[2] => Array
(
[PROD2] => color=metallic_silver
)
[3] => Array
(
[PROD2] => paper=a1
)
)
)
I want to convert this array into this form
Array
(
[5316] => Array
(
[PROD1] => Array
(
color => black
paper => a1
)
[PROD2] => Array
(
color => metallic_silver
paper => a1
)
)
)
If you can't hardcode that key to directly point to it, you can use reset() in this case, then grouped them inside a foreach accordingly. Example:
$array = array(
5316 => array(
array('PROD1' => 'color=black'),
array('PROD1' => 'paper=a1'),
array('PROD2' => 'color=metallic_silver'),
array('PROD2' => 'paper=a1'),
),
);
$grouped = array();
// point it to the first key which gives an array of those values
foreach (reset($array) as $key => $value) {
reset($value); // reset the internal pointer of the sub array
$key = key($value); // this return `PROD1, PROD2`
$grouped[$key][] = current($value); // current gives color=black, the values
}
$array[key($array)] = $grouped; // then reassign
echo '<pre>';
print_r($array);
Sample Output
You can try something like below.
$newArr = [];
$count = count($arr[5316]);
for($i = 0, $j = 1; $i < $count; $i += 2){
$color = explode('=', $arr[5316][$i]['PROD'.$j]);
$paper = explode('=', $arr[5316][$i+1]['PROD'.$j]);
$newArr[5316]['PROD'.$j] = array('color'=>$color[1], 'paper'=>$paper[1]);
$j++;
}
//To show output
print '<pre>';
print_r($newArr);
print '</pre>';

Associative index array to associative associative array

Problem
I have an array which is returned from PHPExcel via the following
<?php
require_once 'PHPExcel/Classes/PHPExcel/IOFactory.php';
$excelFile = "excel/1240.xlsx";
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objPHPExcel = $objReader->load($excelFile);
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
$arrayData[$worksheet->getTitle()] = $worksheet->toArray();
}
print_r($arrayData);
?>
This returns:
Array
(
[Films] => Array
(
[0] => Array
(
[0] => Name
[1] => Rating
)
[1] => Array
(
[0] => Shawshank Redemption
[1] => 39
)
[2] => Array
(
[0] => A Clockwork Orange
[1] => 39
)
)
[Games] => Array
(
[0] => Array
(
[0] => Name
[1] => Rating
)
[1] => Array
(
[0] => F.E.A.R
[1] => 4
)
[2] => Array
(
[0] => World of Warcraft
[1] => 6
)
)
)
What I would like to have is
Array
(
[Films] => Array
(
[0] => Array
(
[Name] => Shawshank Redemption
[Rating] => 39
)
[1] => Array
(
[Name] => A Clockwork Orange
[Rating] => 39
)
)
[Games] => Array
(
[0] => Array
(
[Name] => F.E.A.R
[Rating] => 4
)
[1] => Array
(
[Name] => World of Warcraft
[Rating] => 6
)
)
)
The arrays names (Films, Games) are taken from the sheet name so the amount can be variable. The first sub-array will always contain the key names e.g. Films[0] and Games[0] and the amount of these can be varible. I (think I) know I will need to do something like below but I'm at a loss.
foreach ($arrayData as $value) {
foreach ($value as $rowKey => $rowValue) {
for ($i=0; $i <count($value) ; $i++) {
# code to add NAME[n] as keys
}
}
}
I have searched extensively here and else where if it is a duplicate I will remove it.
Thanks for any input
Try
$result= array();
foreach($arr as $key=>$value){
$keys = array_slice($value,0,1);
$values = array_slice($value,1);
foreach($values as $val){
$result[$key][] = array_combine($keys[0],$val);
}
}
See demo here
You may use nested array_map calls. Somehow like this:
$result = array_map(
function ($subarr) {
$names = array_shift($subarr);
return array_map(
function ($el) use ($names) {
return array_combine($names, $el);
},
$subarr
);
},
$array
);
Demo
Something like this should work:
$newArray = array();
foreach ($arrayData as $section => $list) {
$newArray[$section] = array();
$count = count($list);
for ($x = 1; $x < $count; $x++) {
$newArray[$section][] = array_combine($list[0], $list[$x]);
}
}
unset($arrayData, $section, $x);
Demo: http://ideone.com/ZmnFMM
Probably a little late answer, but it looks more like your tried solution
//Films,Games // Row Data
foreach ($arrayData as $type => $value)
{
$key1 = $value[0][0]; // Get the Name Key
$key2 = $value[0][1]; // Get the Rating Key
$count = count($value) - 1;
for ($i = 0; $i < $count; $i++)
{
/* Get the values from the i+1 row and put it in the ith row, with a set key */
$arrayData[$type][$i] = array(
$key1 => $value[$i + 1][0],
$key2 => $value[$i + 1][1],
);
}
unset($arrayData[$type][$count]); // Unset the last row since this will be repeated data
}
I think this will do:
foreach($arrayData as $key => $array){
for($i=0; $i<count($array[0]); $i++){
$indexes[$i]=$array[0][$i];
}
for($i=1; $i<count($array); $i++){
for($j=0; $j<count($array[$i]); $j++){
$temp_array[$indexes[$j]]=$array[$i][$j];
}
$new_array[$key][]=$temp_array;
}
}
print_r($new_array);
EDIT: tested and updated the code, works...

convert array into key value pairs

I have following array,
Array
(
[Char100_1] => Array
(
[0] => Array
(
[Char100_1] => Mr S Kumar
)
[1] => Array
(
[Char100_1] => Mr S Kumar2
)
)
[Char100_13] => Array
(
[0] => Array
(
[Char100_13] => 159.9
)
[1] => Array
(
[Char100_13] => 119.9
)
)
[Char100_14] => Array
(
[0] => Array
(
[Char100_14] => 191.88
)
[1] => Array
(
[Char100_14] => 143.88
)
)
)
which is created dynamically from a database query result and some loops.
Now I wanted to convert this array into something like below,
Array
(
[0] => Array
(
[Char100_1] => Mr S Kumar
[Char100_13] => 159.9
[Char100_14] => 191.88
)
[1] => Array
(
[Char100_1] => Mr S Kumar2
[Char100_13] => 119.9
[Char100_14] => 143.88
)
)
I have tried looping through them but its not working.
<?php
/* database process to create array */
$contentArray = array();
foreach($newData['DataField'] as $ndata) :
$responsedata = getAppContent($appid, $ndata);
while($haveresult = mysql_fetch_assoc($responsedata))
{
$contentArray[$ndata][] = $haveresult;
}
endforeach;
/* for getting resulting array start */
$newdataArray = array();
foreach($contentArray as $field => $value):
$newdataArray[$field] = array();
foreach( $value as $val ) :
$newdataArray[$field] = $val;
endforeach;
endforeach;
?>
If you can't change the query (as suggested in the comments), then the following should work:
$output = array();
foreach ($array as $a) {
foreach ($a as $k => $b) {
if (empty($output[$k])) {
$output[$k] = array();
}
$output[$k] += $b;
}
}
I observe that you are transposing the arrays. i.e all the zero subscript values together and all the one subscript values together.
Therefore your outer subscript should be the '0' and '1'. These are available in the inner loop. So, the inner loop index becomes the outer array index. And the inner loop value, which is an array, you need to take the 'current' value of.
/* for getting resulting array start (PHP 5.3.18) */
$newdataArray = array();
foreach($contentArray as $field => $value):
foreach( $value as $idx => $val ): // $idx takes value 0 or 1. $val is an array
$newdataArray[$idx][$field] = current($val);
endforeach;
endforeach;
print_r($newdataArray);
As long as all of your arrays have the same amount of values containing them a for loop will do:
$NewDataArray = array();
for ($a = 0; $a < $Numberofvaluesineacharray; $a++){
$NewDataArray[$a] = $NewDataArray[$array1[$a], $array2[$a],.....arrayn[$a];
}

Categories