Remove the value of multidimension element from array if it is duplicated? - php

I have an multidimension array look like this
$input = Array
(
[222] => Array
(
'id' => 222
'val' => 'def'
'more' => 'test'
),
[223] => Array
(
'id' => 223
'val' => 'aaa'
'more' => 'aaa'
),
[224] => Array
(
'id' => 224
'val' => 'aaa'
'more' => 'ddd'
)
[225] => Array
(
'id' => 225
'val' => 'def'
'more' => 'test'
)
);
*Duplicate Because its values of keys val and more duplicated
I want to remove the duplicate value (in this case the $input[222] and $input[225].so the result should only
$res = Array
(
[222] => Array
(
'id' => 222
'val' => 'def'
'more' => 'test'
),
[223] => Array
(
'id' => 223
'val' => 'aaa'
'more' => 'aaa'
),
[224] => Array
(
'id' => 224
'val' => 'aaa'
'more' => 'ddd'
)
);
Anyone know how to do this?
thanks

$newInput = array();
foreach($input as $k => $v) $newInput[$v['val'].$v['more']] = $v;
//You may stop here.
$newInputNum = array();
foreach($newInput as $k => $v) $newInputNum[$v['id']] = $v;
echo "<pre>";print_r($newInputNum );echo "</pre>";

Related

How to Filter multidimensional array and create a new array

I have this kind of array , based on Page ID like : 32,143.
I want to search if array key position have both value in it , then ignore prepend and append value and consider ONLY both value.
And if the array has NO both value and multiple prepend and append value, then it will consider based on priority key.
$sort_result = Array
(
[32] => Array
(
[0] => Array
(
[page] => 32
[position] => append
[priority] => 1
)
[1] => Array
(
[page] => 32
[position] => append
[priority] => 2
)
[2] => Array
(
[page] => 32
[position] => prepend
[priority] => 3
)
[3] => Array
(
[page] => 32
[position] => both
[priority] => 3
)
[4] => Array
(
[page] => 32
[position] => prepend
[priority] => 4
)
)
[143] => Array
(
[0] => Array
(
[page] => 143
[position] => prepend
[priority] => 19
)
[1] => Array
(
[page] => 143
[position] => prepend
[priority] => 18
)
[2] => Array
(
[page] => 143
[position] => append
[priority] => 18
)
)
)
I tried the following code , but not working :
<?php
foreach ( $modify_array as $key => $value ) {
foreach( $value as $k1 => $v1) {
if ( array_search( "both", $v1 ) ) {
$final_array[$key][$k1] = $v1;
} else{
if ( array_search( "prepend", $v1 ) ) {
$final_array[$key][$k1] = $v1;
}
if ( array_search( "append", $v1 ) ) {
$final_array[$key][$k1] = $v1;
}
}
break;
}
}
I am expecting output like this :
Array
(
[32] => Array
(
[3] => Array
(
[page] => 32
[position] => both
[priority] => 3
)
)
[143] => Array
(
[1] => Array
(
[page] => 143
[position] => prepend
[priority] => 18
)
[2] => Array
(
[page] => 143
[position] => append
[priority] => 18
)
)
)
EDIT 1 :
I manage to work , using this code
$modify_array = array();
foreach ( $sort_result as $sort_result_key => $sort_result_value ) {
$modify_array[$sort_result_value['page']][] = $sort_result_value;
}
foreach ( $modify_array as $key => $value ) {
$filter_array[$key]['both_yes'] = array_keys(array_column($value, 'position'),'both');
$filter_array[$key]['prepend_yes'] = array_keys( array_column($value, 'position'),'prepend');
$filter_array[$key]['append_yes'] = array_keys(array_column($value, 'position'),'append');
}
foreach ( $filter_array as $filter_array_key => $filter_array_value ) {
if ( ! empty( $filter_array_value['both_yes'])) {
$a = $filter_array_value['both_yes'][0];
$final_array[] = $modify_array[$filter_array_key][$a];
} else {
if ( ! empty( $filter_array_value['prepend_yes'])) {
$b = $filter_array_value['prepend_yes'][0];
$final_array[] = $modify_array[$filter_array_key][$b];
}
if ( ! empty( $filter_array_value['append_yes'])) {
$c = $filter_array_value['append_yes'][0];
$final_array[] = $modify_array[$filter_array_key][$c];
}
}
}
Edit 2 : var_export
array ( 32 => array ( 0 => array ( 'page' => '32', 'position' => 'append', 'priority' => '1', ), 1 => array ( 'page' => '32', 'position' => 'append', 'priority' => '2', ), 2 => array ( 'page' => '32', 'position' => 'prepend', 'priority' => '3', ), 3 => array ( 'page' => '32', 'position' => 'both', 'priority' => '3', ), 4 => array ( 'page' => '32', 'position' => 'prepend', 'priority' => '4', ), ), 143 => array ( 0 => array ( 'page' => '143', 'position' => 'prepend', 'priority' => '18', ), 1 => array ( 'page' => '143', 'position' => 'append', 'priority' => '18', ), 2 => array ( 'page' => '143', 'position' => 'prepend', 'priority' => '19', ), ), )
I think the lowest time complexity that I can boil this task down to uses 1 full loop of your input array followed by a loop of the grouped data with a nested loop to isolate the rows with the lowest priority value.
The first loop does the grouping and potentially sheds worthless non-both rows for a trivial memory savings.
The second loop iterates the page groups, then the inner loop favors both rows and only uses non-both rows if there are no both rows. The if and elseif ensure that only the rows with the lowest priority number are retained. I added a rsort() call with the assumption that you want prepend rows before append rows. If the position values don't need to be prioritized, then omit the condition block containing the rsort() call.
Code: (Demo)
$array = [
['page' => '32', 'position' => 'append', 'priority' => '1'],
['page' => '32', 'position' => 'append', 'priority' => '2'],
['page' => '32', 'position' => 'prepend', 'priority' => '3'],
['page' => '32', 'position' => 'both', 'priority' => '3'],
['page' => '32', 'position' => 'prepend', 'priority' => '4'],
['page' => '143', 'position' => 'prepend', 'priority' => '18'],
['page' => '143', 'position' => 'append', 'priority' => '18'],
['page' => '143', 'position' => 'prepend', 'priority' => '19'],
];
$result = [];
foreach ($array as $row) {
if (!isset($result[$row['page']])) {
$result[$row['page']] = ['both' => [], 'non-both' => []];
}
if ($row['position'] !== 'both') {
if ($result[$row['page']]['both']) {
continue; // nothing worth doing in this case, ignore the row
} else {
$result[$row['page']]['non-both'][] = $row;
}
} else {
$result[$row['page']]['both'][] = $row;
}
}
foreach ($result as $page => $rows) {
$keep = [];
foreach ($rows['both'] ?: $rows['non-both'] as $row) {
if (!$keep || $row['priority'] < $keep[0]['priority']) {
$keep = [$row];
} elseif ($row['priority'] === $keep[0]['priority']) {
$keep[] = $row;
}
}
if ($keep[0]['position'] !== 'both') {
rsort($keep); // assuming you need prepend to occur before append
}
$result[$page] = $keep;
}
var_export($result);

Nested array, replace alphabetical keys with numeric and keep structure

I have a nested array who is 4 levels deep.
I would like to replace the keys by numerical ones but not the meta level, this array should keep the alphabetical keys.
The array will have a lot of values and there will be more accounts like Marco Mueller, this is just a short example. It is important that it will keep the same nested structure, after its replaced by numerical keys.
$array = array (
'Marco Mueller' =>
array (
'meta' =>
array (
'accountName' => 'Marco Mueller',
'accountId' => '1',
'sum' => '3,659.06',
),
'Conrad, Ute' =>
array (
'meta' =>
array (
'customerName' => 'Conrad, Ute',
'customerId' => '8391',
'sum' => '457.59',
),
'Fidor Bank' =>
array (
'meta' =>
array (
'bankName' => 'Fidor Bank',
'bankKey' => 'FID',
'sum' => '457.59',
),
'H1-2019' =>
array (
'meta' =>
array (
'periodName' => 'H1-2019',
'periodId' => '5',
'sum' => '457.59',
),
),
),
),
),
);
The result should be
$array = array (
array (
'meta' =>
array (
'accountName' => 'Marco Mueller',
'accountId' => '1',
'sum' => '3,659.06',
),
'items' => array (
'meta' =>
array (
'customerName' => 'Conrad, Ute',
'customerId' => '8391',
'sum' => '457.59',
),
'items' =>
array (
'meta' =>
array (
'bankName' => 'Fidor Bank',
'bankKey' => 'FID',
'sum' => '457.59',
),
'items' => array (
'meta' =>
array (
'periodName' => 'H1-2019',
'periodId' => '5',
'sum' => '457.59',
),
),
),
array (
'meta' =>
array (
'periodName' => 'H2-2019',
'periodId' => '6',
'sum' => '600',
),
),
),
),
),
);
I solved my problem with this function, if anyone has an idea how to make this more elegant and efficient, your welcome!
private function getValues(array $array)
{
$newArray = [];
foreach ($array as $item) {
$meta = $item['meta'];
unset($item['meta']);
$arrayValues = array_values($item);
if (count($arrayValues) > 1 || count($arrayValues[0]) > 1) {
$arrayValues = $this->getValues($arrayValues);
}
if (!$arrayValues) {
$values = [
'meta' => $meta,
];
} else {
$values = [
'meta' => $meta,
'items' => $arrayValues,
];
}
$newArray[] = $values;
}
return $newArray;
}

Loop through php array content returning content to screen

I have an array that look like this($myArray)
Array ( [0] => Array ( [0] => Array ( [ID] => 322 [Number] => 1 [Date] => 3117-01-41 [example] => Hello )
[1] => Array ( [ID] => 123 [Number] => 49 [Date] => 1717-05-21 [example] => Hi )
[2] => Array ( [ID] => 007A [Number] => 42 [Date] => 2005-11-24 [example] => Some Text )
[3] => Array ( [ID] => 999AAA [Number] => 492 [Date] => 3117-01-21 [example] => Text Test Text )))
In my page i am using a function which returns content($content) and that content is displayed onto the web browser. No echoing or printing just returning the content variable which is constantly being appended to.
I deally i want to loop through my array and print the values from a certain field to the screen for example
while(//not sure what goes here){
$content .= '<p>'.$someVariable["Number"].'</p>';
$content .= '<p>'.$someVariable["example"].'</p>';
$content .= '<p>'.$someVariable["date"].'</p>';
}
Im not sure if the while loop is the best way to achieve the desired result. Also using fetch_array is not an option i can use because it breaks previous code.
<?php
$yourArray = array (
array (
'ID' => 322,
'Number' => 1,
'Date' => '3117-01-41',
'example' => 'Hello'
),
array (
'ID' => 123,
'Number' => 49,
'Date' => '1717-05-21',
'example' => 'Hi'
),
array (
'ID' => '007A',
'Number' => 42,
'Date' => '2005-11-24',
'example' => 'Some Text'
),
array (
'ID' => '999AAA',
'Number' => 492,
'Date' => '3117-01-21',
'example' => 'Text Test Text'
)
);
?>
print whole array:
<?php print_r($yourArray); ?>
print certain levels of array:
<?php print_r($yourArray[2]); ?>
print certain element of array:
print_r($yourArray[2]['Date']);
print array level by level:
<?php
for($index=0; $index < count($yourArray); $index++){
echo $yourArray[$index]['ID'].'<br>';
echo $yourArray[$index]['Number'].'<br>';
echo $yourArray[$index]['Date'].'<br>';
echo $yourArray[$index]['example'].'<br>';
};
?>
This helps?
<?php
$yourArray = array (
array (
'ID' => 322,
'Number' => 1,
'Date' => '3117-01-41',
'example' => 'Hello'
),
array (
'ID' => 123,
'Address' => '1283 street, 576',
'Date' => '1717-05-21',
'country' => 'Canada'
),
array (
'ID' => '007A',
'Number' => 42,
'Date' => '2005-11-24',
'example' => 'Some Text'
),
array (
'ID' => '999AAA',
'Number' => 492,
'Date' => '3117-01-21',
'example' => array(
'subID' => 45,
'subAlias' => 'teste sub item'
)
)
);
$output = "";
function walkerFunction($item, $key) {
global $output;
$output .= $key . "->" . $item . PHP_EOL;
}
array_walk_recursive($yourArray, "walkerFunction");
echo $output;
It seems you are seeking this:
$yourArray = array (
array (
'ID' => 322,
'Number' => 1,
'Date' => '3117-01-41',
'example' => 'Hello'
),
array (
'ID' => 123,
'Number' => 49,
'Date' => '1717-05-21',
'example' => 'Hi'
),
array (
'ID' => '007A',
'Number' => 42,
'Date' => '2005-11-24',
'example' => 'Some Text'
),
array (
'ID' => '999AAA',
'Number' => 492,
'Date' => '3117-01-21',
'example' => 'Text Test Text'
)
);
$content = '';
foreach($yourArray as $key => $value):
$content .= '<p>'.$value["Number"].'</p>';
$content .= '<p>'.$value["example"].'</p>';
$content .= '<p>'.$value["Date"].'</p>';
endforeach;
print $content;

convert indexed multidimensional array to associative multidimensional array

I have an indexed array with nested categories like this:
array (
0 =>
array (
'name' => 'Furniture',
'id' => 'b3cdd1k',
'content' =>
array (
0 =>
array (
'name' => 'Tables',
'id' => 'nw24ga3',
'content' =>
array (
0 =>
array (
'name' => 'Wooden tables',
'id' => 'ba5lgaz',
),
1 =>
array (
'name' => 'Glass tables',
'id' => 'rqt91gz',
),
),
),
),
),
1 =>
array (
'name' => 'Lamps',
'id' => 'vb1a4nf',
),
2 =>
array (
'name' => 'Doors',
'id' => 'a5l4gal',
'content' =>
array (
0 =>
array (
'name' => 'Entrance doors',
'id' => 'qwg30fb',
),
),
),
)
Is there elegant way to convert it to associative array (where keys are id's) and keep nesting structure?
After conversion I excepting something like this:
array (
'b3cdd1k' =>
array (
'name' => 'Furniture',
'content' =>
array (
'nw24ga3' =>
array (
'name' => 'Tables',
'content' =>
array (
'ba5lgaz' =>
array (
'name' => 'Wooden tables',
),
'rqt91gz' =>
array (
'name' => 'Glass tables',
),
),
),
),
),
'vb1a4nf' =>
array (
'name' => 'Lamps',
),
'a5l4gal' =>
array (
'name' => 'Doors',
'content' =>
array (
'qwg30fb' =>
array (
'name' => 'Entrance doors',
),
),
),
)
You could try this - not the most elegant, but seems to work:
function convert(&$a)
{
$result = Array();
foreach($a as $k=>&$v)
{
$result[$v['id']]['name'] = $v['name'];
if(is_array($v['content'])) $result[$v['id']]['content'] = convert($v['content']);
}
return $result;
}
if(count($array) != 0) $result = convert($array);

calculate the difference between two array

In PHP, how can I compare two array and get result in a third array ?
This result must contain old and new values. The goal is to display an HTML table with a header like "field | old value | new value" as this, the user can compare all values one by one.
First array :
$array1 = array(
'key1' => array(
'key1.1' => 'value',
'key1.2' => 'value',
),
'key2' => array(
'key2.1' => 'value',
'key2.2' => 'value',
),
'key3' => array(
array('key3.1' => 'value'),
array('key3.2' => 'value'),
),
);
Second array :
$array2 = array(
'key1' => array(
'key1.1' => 'value',
'key1.2' => 'value',
),
'key2' => array(
'key2.1' => 'value',
'key2.2' => 'value',
),
'key3' => array(
array('key3.1' => 'value'),
array('key3.2' => 'value'),
),
);
What I expect :
$results = array(
'key1' => array(
'key1.1' => array(
'old' => 'old_value',
'new' => 'new_value',
),
'key1.2' => array(
'old' => 'old_value',
'new' => 'new_value',
),
),
'key2' => array(
'key2.1' => array(
'old' => 'old_value',
'new' => 'new_value',
),
'key2.2' => array(
'old' => 'old_value',
'new' => 'new_value',
),
),
'key3' => array(
array(
'key3.1' => array(
'old' => 'old_value',
'new' => 'new_value')
),
array(
'key3.1' => array(
'old' => 'old_value',
'new' => 'new_value'),
)
),
);
What I have already tried without success :
function array_diff_assoc_recursive($array1, $array2) {
$exclude = array(
'custom_key'
);
$difference = array();
foreach($array1 as $key => $value) {
if(is_array($value)){
if( !isset($array2[$key]) || !is_array($array2[$key]) ) {
if(!in_array($key,$exclude)){
$difference[$key]['old'] = $value;
$difference[$key]['new'] = $array2[$key];
}
} else {
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
if(!empty($new_diff))
$difference[$key] = $new_diff;
}
} else if(!array_key_exists($key,$array2) || $array2[$key] !== $value) {
if(!in_array($key,$exclude)){
$difference[$key]['old'] = $value;
$difference[$key]['new'] = $array2[$key];
}
}
}
return $difference;
}
try this code, i'm sure this will work for you
<?php
echo "<pre>";
$array1 = array(
'key1' => array(
'key1.1' => 'aaa',
'key1.2' => 'xxx',
'key1.3' => 'vvv',
),
'key2' => array(
'key2.1' => 'eee',
'key2.2' => 'fff',
'key2.3' => 'ggg',
),
) ;
echo "Array 1: </br>";
print_r($array1);
$array2 = array(
'key1' => array(
'key1.1' => 'aaa',
'key1.2' => 'ddd',
'key1.3' => 'ccc',
),
'key2' => array(
'key2.1' => 'hhh',
'key2.2' => 'fff',
'key2.3' => 'ttt',
),
);
echo "Array 2:</br>";
print_r($array2);
$result='';
foreach($array1 as $key=> $val)
{
foreach($val as $k=> $v)
{
if($v != $array2[$key][$k])
{
$result[$key][$k]['old']= $array2[$key][$k] ;
$result[$key][$k]['new']= $v;
}
}
}
echo "Compared Result: </br>";
echo "<pre>"; print_r($result);
?>
This will Output
Array 1:
Array
(
[key1] => Array
(
[key1.1] => aaa
[key1.2] => xxx
[key1.3] => vvv
)
[key2] => Array
(
[key2.1] => eee
[key2.2] => fff
[key2.3] => ggg
)
)
Array 2:
Array
(
[key1] => Array
(
[key1.1] => aaa
[key1.2] => ddd
[key1.3] => ccc
)
[key2] => Array
(
[key2.1] => hhh
[key2.2] => fff
[key2.3] => ttt
)
)
Compared Result:
Array
(
[key1] => Array
(
[key1.2] => Array
(
[old] => ddd
[new] => xxx
)
[key1.3] => Array
(
[old] => ccc
[new] => vvv
)
)
[key2] => Array
(
[key2.1] => Array
(
[old] => hhh
[new] => eee
)
[key2.3] => Array
(
[old] => ttt
[new] => ggg
)
)
)
Prepare arrays using array_walk_recursive, and combine them. Please note that the original arrays will be changed
array_walk_recursive($array1, function(&$i) { if(!is_array($i)) $i = array('old'=> $i); });
array_walk_recursive($array2, function(&$i) { if(!is_array($i)) $i = array('new'=> $i); });
print_r(array_merge_recursive($array1, $array2));
demo

Categories