How to merge array by taking values from other array in php - php

I have two arrays like this
$array1 = ['name'=>'john', 'age'=> 10]
$array2 = ['name' => 'johnKaff', 'class' => 'User', 'option'=array('c1', 'c2')]
The result i want is
$array2 = ['name' => 'john', 'class' => 'User', 'option'=array('c1', 'c2'), 'age'=> 10]
The values from $array1 should always override if have same key in $array2

Use array_replace():
$result = array_replace($array2, $array1);
Where:
$array1 - The array in which elements are replaced.
$array2 - The array from which elements will be extracted.
Output:
Array
(
[name] => john
[class] => User
[option] => Array
(
[0] => c1
[1] => c2
)
[age] => 10
)

Use the + operator:
$combined_array = $array1 + $array2;
The array listed first wins when each array has an element with the same key.
Example:
$array1 = array('name'=>'john', 'age'=> 10);
$array2 = array('name' => 'johnKaff', 'class' => 'User', 'option'=>array('c1', 'c2'));
$combined_array = $array1 + $array2;
var_dump($combined_array);
Output:
array(4) {
["name"]=>
string(4) "john"
["age"]=>
int(10)
["class"]=>
string(4) "User"
["option"]=>
array(2) {
[0]=>
string(2) "c1"
[1]=>
string(2) "c2"
}
}

You should use array_merge:
array_merge($array1, $array2);

Related

How to get the difference between two multidimensional arrays of associative arrays in PHP? [duplicate]

This question already has answers here:
Compare 2-dimensional data sets based on a specified second level value
(9 answers)
Closed last year.
My problem is that I have two arrays that are not necessarily the same size that contain associative arrays which are always of the same size, for example:
$a = array([0] => array(["ref"]=> string(19) "ygz121byr46dl4795eu", ["place"]=> string(5) "Paris", ["date"]=> string(25) "2012-03-14T16:42:47+01:00", ...),
[1] => array(["ref"]=> string(19) "cer123bur45dl4795ef", ["place"]=> string(8) "New-York", ["date"]=> string(25) "2015-06-14T05:05:49+01:00", ...),
[2] => array(["ref"]=> string(19) "abc123abc12ab1234ab", ["place"]=> string(6) "London", ["date"]=> string(25) "2020-02-12T08:03:39+01:00", ...),
...);
$b = array([0] => array(["ref"]=> string(19) "ygz121byr46dl4795eu", ["place"]=> string(5) "Paris", ["date"]=> string(25) "2012-03-14T16:42:47+01:00", ...),
[1] => array(["ref"]=> string(19) "cer123bur45dl4795ef", ["place"]=> string(8) "New-York", ["date"]=> string(25) "2015-06-14T05:05:49+01:00", ...),
...);
I tried several methods but nothing seems to work, or I only get the keys without the values.
I want to get the difference (all elements in $a not present $b) in an array, so here the result would be :
$result = array( array(["ref"]=> string(19) "abc123abc12ab1234ab", ["place"]=> string(6) "London", ["date"]=> string(25) "2020-02-12T08:03:39+01:00", ...),
...);
The "ref" key is a unique field for each array, so I needed in $result all the documents whose "ref" key is not in $b
EDIT : I found (https://stackoverflow.com/a/42530586/15742179) a way to do it by using array_diff(), array_map(), json_encode() and decode() method. Thanks to Ifnot
// compare all value
$result = array_diff(array_map('json_encode', $a), array_map('json_encode', $b));
// decode the result
$result = array_map('json_decode', $result);
You need to iterate over either the set of elements to be filtered or over the set of filters. This would be a possible approach:
<?php
$a = [
["ref" => "bee898d8739aa8b2212", "place" => "Berlin"],
["ref" => "ygz121byr46dl4795eu", "place" => "Paris"],
["ref" => "cer123bur45dl4795ef", "place" => "New-York"],
["ref" => "abc123abc12ab1234ab", "place" => "London"]
];
$b = [
["ref" => "ygz121byr46dl4795eu", "place" => "Paris"],
["ref" => "cer123bur45dl4795ef", "place" => "New-York"],
];
$filter = array_column($b, "ref");
$result = array_combine(array_column($a, "ref"), $a);
array_walk($filter, function($entry) use (&$result) {
unset($result[$entry]);
});
print_r(array_values($result));
Another approach would be to use php's array_filter() function:
<?php
$a = [
["ref" => "bee898d8739aa8b2212", "place" => "Berlin"],
["ref" => "ygz121byr46dl4795eu", "place" => "Paris"],
["ref" => "cer123bur45dl4795ef", "place" => "New-York"],
["ref" => "abc123abc12ab1234ab", "place" => "London"]
];
$b = [
["ref" => "ygz121byr46dl4795eu", "place" => "Paris"],
["ref" => "cer123bur45dl4795ef", "place" => "New-York"],
];
array_walk($b, function($filter) use (&$a) {
$a = array_filter($a, function($entry) use ($filter) {
return $entry["ref"] != $filter["ref"];
});
});
print_r($a);
The output obviously is:
Array
(
[0] => Array
(
[ref] => bee898d8739aa8b2212
[place] => Berlin
)
[1] => Array
(
[ref] => abc123abc12ab1234ab
[place] => London
)
)
Make one array $c by merging them together,
get uniques ref using functions array_column and array_unique
and also get duplicates by array_diff_assoc, then easily get differences ref using array_diff, then loop over the array and take only their ref in $diff array.
$c = [...$a, ...$b];
$arr = array_column($c, "ref");
$unique = array_unique($arr);
$duplicates = array_diff_assoc($arr, $unique);
$diff = array_diff($unique, $duplicates);
$output = [];
foreach ($c as $d) {
foreach ($d as $key => $value) {
if(in_array($d[$key], $diff))
$output[] = $d;
}
}
echo "<pre>",print_r($output),"</pre>";
Output:
Array
(
[0] => Array
(
[ref] => bee898d8739aa8b2212
[place] => Berlin
)
[1] => Array
(
[ref] => abc123abc12ab1234ab
[place] => London
)
)

how to remove array inside array

I have array in this structure, and I want delete item[6] from array.
I used unset($arrayname[6]) in php but it's not working. Any help? Is there any way I can remove element [6] from array?
array(2) {
[6]=>
array(2) {
["id"]=>
string(1) "1"
["day"]=>
string(6) "Monday"
}
[7]=>
array(2) {
["id"]=>
string(1) "2"
["day"]=>
string(7) "Tuesday"
}}
This works as you would expect:
<?php
$days =
array (
6 =>
array (
'id' => 1,
'day' => 'Mon',
),
7 =>
array (
'id' => 2,
'day' => 'Tue',
)
);
unset($days[6]);
var_export($days);
Output:
array (
7 =>
array (
'id' => 2,
'day' => 'Tue',
),
)
You can use unset() function which removes the element from an array and then use array_values() function which indexes the array numerically.
$array2 = {{array of array}}
// remove item at index 6 which is 'for'
unset($array2[6]);
// Print modified array
var_dump($array2);
// Re-index the array elements
$arr2 = array_values($array2);
//Print re-indexed array
var_dump($array2);
This solution will work, please check and let me know.

Sort array elements based on another array's keys

In my PHP file I have 2 arrays, in each one the keys are numbered from 0 to its last index, and they both contains the same array elements number, as they are containing data on the same contact, but each array contains a different data about the same contact, and each contact has an ID which is his index on the array.
I have sorted the first array descending according to the values, so the keys are in different sort, and the values are descending. I want to sort the second array, in the same way, so they would have the same keys order, and then to do array_values on both of the arrays, in order it to have new ascending keys order.
For example I have these 2 arrays:
$arr1 = array('0' => 'John', '1' => 'George', '2' => 'James', '3' => 'Harry');
$arr2 = array('0' => '12', '1' => '8', '2' => '34', '3' => '23');
I have sorted $arr2 descending according to his values like this:
arsort($arr2);
// So now, $arr2 is "[2] => '34', [3] => '23', [0] => '12', [1] => '8'"
I want to sort $arr1 in the same way so it will also be:
$arr1 = array('2' => '34', [3] => '23', [0] => '12', [1] => '8');
How can I do this so the arrays will be sorted in the same keys order?
How about this? Using array_replace():
<?php
$arr1 = array('0' => 'John', '1' => 'George', '2' => 'James', '3' => 'Harry');
$arr2 = array('0' => '12', '1' => '8', '2' => '34', '3' => '23');
arsort($arr2);
var_dump(array_replace($arr2, $arr1)); // array(4) { [2]=> string(5) "James" [3]=> string(5) "Harry" [0]=> string(4) "John" [1]=> string(6) "George" }
Demo
How about using array_multi_sort()? It rearranges all arrays to match the order of the first sorted array.
// as elements of $arr2 are shifted, corresponding elements of $arr1 will have the same shift
array_multisort($arr2, SORT_DESC, $arr1);
Live demo
So you have two arrays, so why not just loop over the second array and use its as a key order to create a new array using the the values from the 1st array..
$newArray = array();
foreach (array_keys($arr2) as $key) {
$newArray[$key] = $arr1[$key];
}
// then apply sorting to new array
arsort($newArray);
Then simply print your new array $newArray to check your result.
print_r($newArray) or var_dump($newArray)
Expected output will be:
array(4) {
[0]=>
string(4) "John"
[2]=>
string(5) "James"
[3]=>
string(5) "Harry"
[1]=>
string(6) "George"
}
Similarly if you want an opposite, Then change just replace $arr2 with $arr1 like wise.
$newArray = array();
foreach (array_keys($arr1) as $key) {
$newArray[$key] = $arr2[$key];
}
// then apply sorting to new array
arsort($newArray);
var_dump($newArray)`
Expected output will be:
array(4) {
[2]=>
string(2) "34"
[3]=>
string(2) "23"
[0]=>
string(2) "12"
[1]=>
string(1) "8"
}

Remove similar objects from array?

I have an array of objects, but I need to remove a similar objects by a few properties from them:
for example:
array(12) {
[0]=>
object(stdClass)#848 (5) {
["variant"]=>
object(stdClass)#849 (4) {
["name"]=>
string(8) "Alex"
}
["age"]=>
int(10)
}
[1]=>
object(stdClass)#851 (5) {
["variant"]=>
object(stdClass)#852 (4) {
["name"]=>
string(8) "Alex"
}
["age"]=>
int(10)
}
How to make a one object in array for this ( if for example I need to compare only by a name property? )
Still have an issue with it.
Updated
I've create a new array of objects:
$objects = array(
(object)array('name'=>'Stiven','age'=>25,'variant'=>(object)array('surname'=>'Sigal')),
(object)array('name'=>'Michael','age'=>30,'variant'=>(object)array('surname'=>'Jackson')),
(object)array('name'=>'Brad','age'=>35,'variant'=>(object)array('surname'=>'Pit')),
(object)array('name'=>'Jolie','age'=>35,'variant'=>(object)array('surname'=>'Pit')),
);
echo "<pre>";
print_r($objects);
So what I need to do is to compare an object properties (variant->surnames and ages), if two objects has a similar age and variant->surname we need to remove the one of these objects.
A half of solution is:
$tmp = array();
foreach ($objects as $item=>$object)
{
$tmp[$object->variant->surname][$object->age] = $object;
}
print_r($tmp);
Unfortunatelly I need an old-style array of objects.
I've found an example.
<?php
$a = array (
0 => array ( 'value' => 'America', ),
1 => array ( 'value' => 'England', ),
2 => array ( 'value' => 'Australia', ),
3 => array ( 'value' => 'America', ),
4 => array ( 'value' => 'England', ),
5 => array ( 'value' => 'Canada', ),
);
$tmp = array ();
foreach ($a as $row)
if (!in_array($row,$tmp)) array_push($tmp,$row);
print_r ($tmp);
?>
Quoted from here

Search key replace value

Let's say I have an array:
$myArray = array('alfa' => 'apple', 'bravo' => 'banana', 'charlie' => 'cherry', 'delta' => 'danjou pear');
I want to search it for certain keys and if found replace the values of those according to this other array:
$myReplacements = array('bravo' => 'bolognese', 'lie' => 'candy');
I know I can do this:
function array_search_replace($haystack, $replacements, $exactMatch = false) {
foreach($haystack as $haystackKey => $haystackValue) {
foreach($replacements as $replacementKey => $replacementValue) {
if($haystackKey == $replacementKey || (!$exactMatch && strpos($haystackKey, $replacementKey) !== false)) {
$haystack[$haystackKey] = $replacementValue;
}
}
}
return $haystack;
}
But, is there really no smarter/faster way to do it?
EDIT: I also need to be able to search for keyparts, so that 'lie' and 'charlie' results in a match.
EDIT2: Expected results are:
var_dump(array_search_replace($myArray, $myReplacements));
array(4) { ["alfa"]=> string(5) "apple" ["bravo"]=> string(9) "bolognese" ["charlie"]=> string(5) "candy" ["delta"]=> string(11) "danjou pear" }
var_dump(array_search_replace($myArray, $myReplacements, true));
array(4) { ["alfa"]=> string(5) "apple" ["bravo"]=> string(9) "bolognese" ["charlie"]=> string(6) "cherry" ["delta"]=> string(11) "danjou pear" }
You can use the PHP's array_replace function.
Also, array_merge does something similar.
In your code:
$finalArray = array_replace($myArray, $myReplacements);
Full PHP Code
<?php
$myArray = array('alfa' => 'apple', 'bravo' => 'banana', 'charlie' => 'cherry', 'delta' => 'danjou pear');
$myReplacements = array('bravo' => 'bolognese', 'lie' => 'candy');
$finalArray = array_replace($myArray, $myReplacements);
print_r($finalArray);
?>
Output
Array
(
[alfa] => apple
[bravo] => bolognese
[charlie] => cherry
[delta] => danjou pear
[lie] => candy
)
Fiddle here: http://codepad.viper-7.com/60o5xT
Is this what you need ?
<?php
$myArray = array('alfa' => 'apple', 'bravo' => 'banana', 'charlie' => 'cherry', 'delta' => 'danjou pear');
$myReplacements = array('bravo' => 'bolognese', 'lie' => 'candy');
print_r(array_merge($myArray, $myReplacements));
?>
Output:
Array
(
[alfa] => apple
[bravo] => bolognese
[charlie] => cherry
[delta] => danjou pear
[lie] => candy
)
Using array_merge
Arrays in PHP are hashes, you don't need to search for a key, you can access it in O(1) time.
$myArray = array('alfa' => 'apple', 'bravo' => 'banana', 'charlie' => 'cherry', 'delta' => 'danjou pear');
$myReplacements = array('bravo' => 'bolognese', 'lie' => 'candy');
var_dump($myArray);
foreach($myReplacements as $k => $v) {
if(array_key_exists($k, $myArray)) {
$myArray[$k] = $v;
}
}
var_dump($myArray);
Output:
array(4) {
["alfa"]=>
string(5) "apple"
["bravo"]=>
string(6) "banana"
["charlie"]=>
string(6) "cherry"
["delta"]=>
string(11) "danjou pear"
}
array(4) {
["alfa"]=>
string(5) "apple"
["bravo"]=>
string(9) "bolognese"
["charlie"]=>
string(6) "cherry"
["delta"]=>
string(11) "danjou pear"
}
you can use the following code to directly replace the matching key
<?php
$base = array("orange", "banana", "apple", "raspberry");
$replacements = array(0 => "pineapple", 4 => "cherry");
$replacements2 = array(0 => "grape");
$basket = array_replace($base, $replacements, $replacements2);
print_r($basket);
?>
output:
Array
(
[0] => grape
[1] => banana
[2] => apple
[3] => raspberry
[4] => cherry
)

Categories