PHP merge associative arrays with duplicate keys - php

I have an array like this:
$array1 = [
['State'=>'Utah', 'users'=>5],
['State'=>'California', 'users'=>10]
]
$array2 = [
['State'=>'Utah', 'emails'=>18],
['State'=>'Arizona', 'emails'=>32],
['State'=>'California', 'emails'=>28],
]
How would I merge them so that it will become like this:
$mergedArray = [
['State'=>'Utah', 'users'=>5, 'emails'=>18],
['State'=>'Arizona', 'emails'=>32],
['State'=>'California', 'users'=>10, 'emails'=>28]
]
I tried array_merge but it only kept data from the first array.
Edit: Notice how the length and order of the array can be different.

Use array_replace_recursive function:
$array1 = ['Utah'=>['users'=>5],'California'=>['users'=>10]];
$array2 = ['Utah'=>['emails'=>18],'California'=>['emails'=>28]];
$result = array_replace_recursive($array1, $array2);
print_r($result);
The output:
Array
(
[Utah] => Array
(
[users] => 5
[emails] => 18
)
[California] => Array
(
[users] => 10
[emails] => 28
)
)
Update:
Though you have changed your initial requirements I also have solution for your new input data.Used functions: array_merge and array_values
// user data
$array1 = [
['State'=>'Utah', 'users'=>5],
['State'=>'California', 'users'=>10]
];
// email data
$array2 = [
['State'=>'Utah', 'emails'=>18],
['State'=>'Arizona', 'emails'=>32],
['State'=>'California', 'emails'=>28],
];
$result = [];
foreach (array_merge($array1, $array2) as $item) {
if (isset($result[$item['State']])) {
$result[$item['State']] = array_merge($result[$item['State']], $item);
} else {
$result[$item['State']] = $item;
}
}
$result = array_values($result);
print_r($result);
The output:
Array
(
[0] => Array
(
[State] => Utah
[users] => 5
[emails] => 18
)
[1] => Array
(
[State] => California
[users] => 10
[emails] => 28
)
[2] => Array
(
[State] => Arizona
[emails] => 32
)
)

Related

Remove subsets from each row where the same subset is found in another row

I need to remove objects from a 3d array where the same two-property object is found in any other row.
I previously asked this similar question, but my new requirements are slightly different because I was keeping one of the encountered duplicates. Now I would like for both/all encountered duplicates to be removed.
[
[
["name" => "John", "surname" => "Smith"],
["name" => "Kate", "surname" => "Winston"]
],
[
["name" => "Kate", "surname" => "Winston"],
["name" => "Jack", "surname" => "Irving"]
],
]
Desired filtered result with same original structure:
[
[
["name" => "John", "surname" => "Smith"],
],
[
["name" => "Jack", "surname" => "Irving"]
],
]
Seems like others answers don't see their own final results and don't read desired output.
Here a little bit hard solution but it works well.
Note: the input data array must have 2 object indexes and 2 arrays of objects for comparing, otherwise, it should be fixed.
$ar = Array (
0 => [(object)["name"=>"John", "surname"=>"Smith"], (object)["name"=>"Kate", "surname"=>"Winston"]],
1 => [(object)["name"=>"Kate", "surname"=>"Winston"], (object)["name"=>"Jack", "surname"=>"Irving"]]
);
$arr = [];
$k = 0; // do `if statement` only once
foreach($ar as $num=>&$subar){
foreach($subar as $num2=>$pers){
$subar[$num2] = (array)$pers; // object to array
if (!$k) {
$keys = array_keys($subar[$num2]); // collect "name" and "surname" in an array
$k++;
}
foreach($subar[$num2] as $a=>$b){
$seq = array_search($a,$keys); // index of the current key
if (!$seq) { // 0 -> "name", 1 -> "surname"
$arr[$num][$b] = '';
} else {
$arr[$num][$subar[$num2][current($keys)]] = $b;
}
}
}
}
$diff[] = array_diff($arr[0],$arr[1]); // clear duplicates from 1-st set
$diff[] = array_diff($arr[1],$arr[0]); // clear duplicates from 2-nd set
Gives result:
Array
(
[0] => Array
(
[John] => Smith
)
[1] => Array
(
[Jack] => Irving
)
)
And after you can re-create the output array:
// creating a new array
$res = [];
foreach($diff as $num=>$ns){
foreach($ns as $name=>$surname){
foreach($keys as $ind=>$key){
if ($ind % 2 == 0){
$tmp[$key] = $name; // put name
} else {
$tmp[$key] = $surname; // put surname
}
}
$res[$num] = (object)$tmp; // array to object
}
}
Output will be:
Array
(
[0] => stdClass Object
(
[name] => John
[surname] => Smith
)
[1] => stdClass Object
(
[name] => Jack
[surname] => Irving
)
)
Demo
In case of string values in the input arrays, i.e.:
$ar = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
You need a little fix:
...
foreach($ar as $num=>&$subar){
$ar[$num] = json_decode($subar);
foreach($subar as $num2=>$pers){
...
The same output you will get.
Demo
It's easier if you don't trim away the brackets [], as you stated that you did in the comments. That way, they are proper JSON strings, which we can use in PHP.
Map (or loop) over your array, and build up a $result array, where you append all the arrays from your decoded JSON. Once you have your final $result, you have an array that looks somewhat like
Array (
[0] => Array
(
[name] => John
[surname] => Smith
)
[1] => Array
(
[name] => Kate
[surname] => Winston
)
[2] => Array
(
[name] => Kate
[surname] => Winston
)
[3] => Array
(
[name] => Jack
[surname] => Irving
)
)
We have all the values in an actual array now, but there are duplicates -- which can be removed using array_unique() with the SORT_REGULAR flag.
$array = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
$result = [];
array_map(function($v) use (&$result) {
$result = array_merge($result, json_decode($v, true));
}, $array);
print_r(array_unique($result, SORT_REGULAR));
Final output:
Array
(
[0] => Array
(
[name] => John
[surname] => Smith
)
[1] => Array
(
[name] => Kate
[surname] => Winston
)
[3] => Array
(
[name] => Jack
[surname] => Irving
)
)
Live demo at https://3v4l.org/q6pZc
$array = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
$resultArray = [];
foreach ($array as $item) {
$bufferArray = array_merge($resultArray, json_decode($item));
foreach ($bufferArray as $elements) {
$key = $elements->name . $elements->surname;
if (array_key_exists($key, $resultArray)) {
unset($resultArray[$key]);
} else {
$resultArray[$key] = $elements;
}
}
}
print_r($resultArray);
Output
Array
(
[KateWinston] => stdClass Object
(
[name] => Kate
[surname] => Winston
)
[JackIrving] => stdClass Object
(
[name] => Jack
[surname] => Irving
)
)
can rewrite this into more serious code )
To remove objects from each row where a given object exists any where in any other row, you can make iterates calls of array_udiff(). Inside the function, the first parameter should be the currently iterated row and the next/subsequent parameter(s) should all of the other rows in the entire array. The last parameter is the callback which compares whole objects to whole objects via PHP's performance-optimized algorithm.
My snippet below will not only handle your 2-row array, it will also handle arrays with 3 or more rows.
Code: (Demo)
$result = [];
foreach ($array as $i => $objs) {
$cache = $array[$i];
unset($array[$i]);
$params = [
$objs,
...$array,
fn($a, $b) => $a <=> $b
];
$result[] = array_udiff(...$params);
$array[$i] = $cache;
}
var_export($result);
To be clear, this snippet will work the same if the array of arrays of objects is an array of arrays of arrays.

How to split multidimensional array into multiple array dynamically

I got multidimensional arrays i want it to break into multi array in one variable
Array
(
[name] => Array
(
[0] => John Davis
[1] => Marie J
)
[work] => Array
(
[0] => employee
[1] => none
)
[address] => Array
(
[0] => street 1
[1] => street 2
)
)
I want output to :
$array1 = array("name" => "John Davis", "work" => "employee", "address" => "street 1");
$array2 = array("name" => "Marie J", "work" => "none", "address" => "street 2");
and how to generate dynamically if values keys more than 2
thanks alot
Please try below code get output:
$newArray = [];
foreach ($outerArray as $outerkey => $outerArr) {
foreach ($outerArr as $key => $innerArr) {
$newArray[$key][$outerkey] = $innerArr;
}
}
print_r($newArray);
Functional solution
// make array of keys
$keys = array_keys($arr);
// combine it with data sets
$res = array_map(function (...$x) use($keys)
{ return array_combine($keys, $x); },
...array_values($arr));
demo

Remove duplicate array on the base of key in multidimendional array PHP [duplicate]

This question already has answers here:
How to remove duplicate values from a multi-dimensional array in PHP
(18 answers)
Closed 6 years ago.
From following array key with ID 16 is comming twice. Hown can we remove this this duplicate ID. (REMOVE IF ID IS DUPLICATE OTHER FIELDS IGNORE)
Array
(
[1] => Array
(
[ID] => 16
[username] => dudda
[message-time] => 2016-08-25 12:12:53
)
[2] => Array
(
[ID] => 16
[username] => dudda
[message-time] => 2016-08-25 12:01:54
)
[3] => Array
(
[ID] => 3
[username] => himanshu
[message-time] => 2016-08-15 12:53:38
)
[4] => Array
(
[ID] => 15
[username] => dawinder
[message-time] => 2016-08-10 11:40:33
)
)
I Got solution
I have develop this function for same :
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;
}
Now, call this function anywhere from your code,
something like this,
$details = unique_multidim_array($array_name,'key');
We used this to de-duplicate results from a variety of overlapping queries.
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
array array_unique ( array $array [, int $sort_flags = SORT_STRING ] )
Read this:http://php.net/manual/en/function.array-unique.php
For Example
<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>
Output will be:
Array
(
[a] => green
[0] => red
[1] => blue
)

How to convert array into json

I have this type of Array
Array
(
[0] => Samy Jeremiah,55
[1] => Nelson Owen,93
[2] => McMaster Ashlie,88
[3] => Marsh Harlow,97
[4] => Macfarquhar Aiden,95
[5] => Lowe Sophie,91
);
I need to convert this array into following type of json
data: [
['Samy Jeremiah',55 ],
['Nelson Owen',93 ],
['McMaster Ashlie',88 ] ,
['Marsh Harlow',97 ] ,
['Macfarquhar Aiden',95 ],
['Lowe Sophie',91 ]
]
Try this
<?php
$yourArray = array(
'0' => 'Samy Jeremiah,55',
'1' => 'Nelson Owen,93',
'2' => 'McMaster Ashlie,88',
'3' => 'Marsh Harlow,97',
'4' => 'Macfarquhar Aiden,95',
'5' => 'Lowe Sophie,91',
);
#Check output 01
//print_r($yourArray);
foreach ($yourArray as $value) {
$explodeValue = explode( ',', $value );
$newName []= array($explodeValue[0] => $explodeValue[1]);
}
#Check output 02
//print_r($newName);
#Check output 03
echo(json_encode($newName));
?>
PHPFiddle Preview
Output 01
Array (
[0] => Samy Jeremiah,55
[1] => Nelson Owen,93
[2] => McMaster Ashlie,88
[3] => Marsh Harlow,97
[4] => Macfarquhar Aiden,95
[5] => Lowe Sophie,91
)
Output 02
Array (
[0] => Array ( [Samy Jeremiah] => 55 )
[1] => Array ( [Nelson Owen] => 93 )
[2] => Array ( [McMaster Ashlie] => 88 )
[3] => Array ( [Marsh Harlow] => 97 )
[4] => Array ( [Macfarquhar Aiden] => 95 )
[5] => Array ( [Lowe Sophie] => 91 )
)
Output 03
[
{"Samy Jeremiah":"55"},
{"Nelson Owen":"93"},
{"McMaster Ashlie":"88"},
{"Marsh Harlow":"97"},
{"Macfarquhar Aiden":"95"},
{"Lowe Sophie":"91"}
]
Your desired result is an array of arrays. You have to split each entry of your array into 2 entities and push them as an array into a new array, then json_encode() the new array.
This php-snippet only works, if your input is consistantly an array of strings, containing each one comma as separator between name and int-value:
$arr2 = array();
foreach($arr1 as $e) {
list($name, $val) = explode(',', $e);
$arr2[] = array($name, (int)$val);
}
echo json_encode($arr2);
Use below code
$data = array('Samy Jeremiah,55', 'Nelson Owen,93', 'McMaster Ashlie,88', 'Marsh Harlow,97', 'Macfarquhar Aiden,95', 'Lowe Sophie,91');
$res = array();
foreach($data as $e) {
$list = explode(',', $e);
$res[] = array($list[0], $list[1]);
}
echo json_encode(['data'=>$arr2]);
Output
{"data":[
["Samy Jeremiah",55],
["Nelson Owen",93],
["McMaster Ashlie",88],
["Marsh Harlow",97],
["Macfarquhar Aiden",95],
["Lowe Sophie",91]
]
}
Using the json_encode you can achieve what you want.
Suppose your array name is $arr, so now apply the json_encode.
echo json_encode(array('data'=>$arr)); //your json will be print here
Real time Example:
$arr = array('Samy Jeremiah,55', 'Nelson Owen,93', 'McMaster Ashlie,88', 'Marsh Harlow,97', 'Macfarquhar Aiden,95', 'Lowe Sophie,91');
$new_arr = array();
foreach($arr as $k => $val){
$na = explode(",", $val);
$na[0] = "'".$na[0]."'";
$value = implode(",", $na);
$new_arr[$k] = $value;
}
echo json_encode(array("data" => $new_arr));

php array find duplicates, sum them up & delete duplicates

i have an array:
Array
(
[0] => Array
(
[setid] => 2
[income] => 100
)
[1] => Array
(
[setid] => 2
[income] => 120
)
[2] => Array
(
[setid] => 3
[income] => 700
)
)
i need to find entrys with the same setid, sum their income up and delete duplicate entrys - in the end it should look like this:
Array
(
[0] => Array
(
[setid] => 2
[income] => 220
)
[1] => Array
(
[setid] => 3
[income] => 700
)
)
does someone know a sophosticated solution for my problem or do i have to take the long road and do every step manually?
thanks and greetings
Just create a new array which you make fast adressable by using the setid as key. And reindex the array at the end.
$result = array();
foreach ($array as $val) {
if (!isset($result[$val['setid']]))
$result[$val['setid']] = $val;
else
$result[$val['setid']]['income'] += $val['income'];
}
$result = array_values($result); // reindex array
This should work:
$values = array();
foreach($array as $val) {
if(isset($values[$val['setid']])) {
$values[$val['setid']] += $val['income'];
} else {
$values[$val['setid']] = $val['income'];
}
}
//all values are now in $values array, keys are setid and values are income
Write your own function, that's no long road at all.
$result = array_reduce($originalArray, function($memo, $item){
isset($memo[$item['setid']])
? $memo[$item['setid']] = $item['income']
: $memo[$item['setid']] += $item['income'];
return $memo;
}, []);
You should use the array_unique function that php's official site offers.
An example:
<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>
Output:
Array
(
[a] => green
[0] => red
[1] => blue
)
To sum the duplicated values you can use the array_count_values function:
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
Output would be:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)

Categories