Using array_intersect on a multi-dimensional array - php

I have two arrays that both look like this:
Array
(
[0] => Array
(
[name] => STRING
[value] => STRING
)
[1] => Array
(
[name] => STRING
[value] => STRING
)
[2] => Array
(
[name] => STRING
[value] => STRING
)
)
and I would like to be able to replicate array_intersect by comparing the ID of the sub arrays within the two master arrays. So far, I haven't been successful in my attempts. :(

Use array_uintersect() to use a custom comparison function, like this:
$arr1 = array(
array('name' => 'asdfjkl;', 'value' => 'foo'),
array('name' => 'qwerty', 'value' => 'bar'),
array('name' => 'uiop', 'value' => 'baz'),
);
$arr2 = array(
array('name' => 'zxcv', 'value' => 'stuff'),
array('name' => 'asdfjkl;', 'value' => 'foo'),
array('name' => '12345', 'value' => 'junk'),
array('name' => 'uiop', 'value' => 'baz'),
);
$intersect = array_uintersect($arr1, $arr2, 'compareDeepValue');
print_r($intersect);
function compareDeepValue($val1, $val2)
{
return strcmp($val1['value'], $val2['value']);
}
which yields, as you would hope:
Array
(
[0] => Array
(
[name] => asdfjkl;
[value] => foo
)
[2] => Array
(
[name] => uiop
[value] => baz
)
)

function compareDeepValue($val1, $val2)
{
return strcmp($val1['value'], $val2['value']);
}
Be sure that val2 key is existing in val1 array, because the function is ordering array first. Very strange.

you can use embedded function with array_uintersect php function. ex:
$intersectNames = array_uintersect($arr1, $arr2, function ($val1, $val2){
return strcmp($val1['name'], $val2['name']);
});
$intersectValues = array_uintersect($arr1, $arr2, function ($val1, $val2){
return strcmp($val1['value'], $val2['value']);
});
print_r('namesIntersected' => $intersectNames, 'valuesIntersected' => $intersectValues)

Related

Array to string conversion doing array_intersect [duplicate]

I have two arrays that both look like this:
Array
(
[0] => Array
(
[name] => STRING
[value] => STRING
)
[1] => Array
(
[name] => STRING
[value] => STRING
)
[2] => Array
(
[name] => STRING
[value] => STRING
)
)
and I would like to be able to replicate array_intersect by comparing the ID of the sub arrays within the two master arrays. So far, I haven't been successful in my attempts. :(
Use array_uintersect() to use a custom comparison function, like this:
$arr1 = array(
array('name' => 'asdfjkl;', 'value' => 'foo'),
array('name' => 'qwerty', 'value' => 'bar'),
array('name' => 'uiop', 'value' => 'baz'),
);
$arr2 = array(
array('name' => 'zxcv', 'value' => 'stuff'),
array('name' => 'asdfjkl;', 'value' => 'foo'),
array('name' => '12345', 'value' => 'junk'),
array('name' => 'uiop', 'value' => 'baz'),
);
$intersect = array_uintersect($arr1, $arr2, 'compareDeepValue');
print_r($intersect);
function compareDeepValue($val1, $val2)
{
return strcmp($val1['value'], $val2['value']);
}
which yields, as you would hope:
Array
(
[0] => Array
(
[name] => asdfjkl;
[value] => foo
)
[2] => Array
(
[name] => uiop
[value] => baz
)
)
function compareDeepValue($val1, $val2)
{
return strcmp($val1['value'], $val2['value']);
}
Be sure that val2 key is existing in val1 array, because the function is ordering array first. Very strange.
you can use embedded function with array_uintersect php function. ex:
$intersectNames = array_uintersect($arr1, $arr2, function ($val1, $val2){
return strcmp($val1['name'], $val2['name']);
});
$intersectValues = array_uintersect($arr1, $arr2, function ($val1, $val2){
return strcmp($val1['value'], $val2['value']);
});
print_r('namesIntersected' => $intersectNames, 'valuesIntersected' => $intersectValues)

Merge PHP array having same keys different values

I am trying to merge arrays with the same keys with different values, like below.
Input:
$array1 = array('1933' => array(
'nid' => '492811',
'title' => 'NEW TITLE',
'field_link_single_url' => 'abc',
'field_link_single_title' => 'test'
));
$array2 = array('1933' => array(
'nid' => '492811',
'title' => 'NEW TITLE',
'field_link_single_url' => 'xyz',
'field_link_single_title' => 'abcd'
));
Expected output to be:
Array
(
[nid] => 492811
[title] => NEW TITLE
[field_link_single_url] => [
[0] => 'abc',
[1] => 'xyz'
]
[field_link_single_title] => [
[0] => 'test',
[1] => 'abcd'
]
)
I have tried array_merge and array_merge_recursive but it does not work as expected.
Output of array_merge_recursive($array1[1933], $array2[1933]) it is creating duplicates keys having same value
Array
(
[nid] => Array
(
[0] => 492811
[1] => 492811
)
[title] => Array
(
[0] => Hal Louchheim
[1] => Hal Louchheim
)
[field_link_single_url] => Array
(
[0] => abc
[1] => xyz
)
[field_link_single_title] => Array
(
[0] => test
[1] => abcd
)
)
I made some assumption. If these assumptions are not valid, you should add some additional checks:
Both $array1 and $array2 are really arrays
Both $array1 and $array2 have the exact same keys
The values inside $array1 and $array2 are primitive types, not complex objects (the === operator would not work to compare objects or arrays)
function mergeArrayValues($array1, $array2) {
$output = [];
foreach($array1 as $key => $value) {
$output[$key] = $array1[$key] === $array2[$key]
? $array1[$key]
: [ $array1[$key], $array2[$key] ]
}
return $output;
}
mergeArrayValues($array1[1933], $array2[1933])

How to get array intersect with single array group

I have array values in single array and I need to intersect the arrays inside the main array.
Here is my code:
$a[1] = array ( 'value' => 'America','value1' => 'England1','value2' => 'Australia','value3' => 'England','value4' => 'Canada', );
$a[2] = array ( 'value' => 'America','value1' => 'Wales','value2' => 'Australia','value3' => 'England1','value4' => 'Canada', );
$a[3] = array ( 'value' => 'America','value1' => 'England','value2' => 'Australia','value3' => 'England1','value4' => 'Canada', );
I need to show the intersect values in the array. I need the result as follows:
Array
(
[value] => America
[value1] => England1
[value2] => Australia
[value4] => Canada
)
I can't check with this array with array_intersect() function. because array keys are coming in dynamically.
This is just a sample. It goes like:
$a[1],$a[2],$a[3].....$a[n]
So please suggest any solution for this.
You can do this with call_user_func_array:
$result = call_user_func_array("array_intersect", $a);
Its very easy use array_intersect() as follows
$a[1] = array ( 'value' => 'America','value1' => 'England1','value2' => 'Australia','value3' => 'England','value4' => 'Canada' );
$a[2] = array ( 'value' => 'America','value1' => 'Wales','value2' => 'Australia','value3' => 'England1','value4' => 'Canada' );
$a[3] = array ( 'value' => 'America','value1' => 'England','value2' => 'Australia','value3' => 'England1','value4' => 'Canada');
$c=count($a);
$new=a[0];
for($i=0;$i<$c;$i++)
{
$new=array_intersect($new, $a[$i+1]);
}
print_r($new);

How can I group by a count of a subvalue of an array?

I've been trying every combination of array_count_values and array_map I can think of. I'm hoping you can show me the way.
Here's a sample array:
$arr = array(
array('name' => 'foo','score' => 1),
array('name' => 'foo','score' => 2),
array('name' => 'bar','score' => 1)
);
I'd like to combine the scores of all sub values with the same name. Something like GROUP BY name in MySQL.
Array
(
[0] => Array
(
[name] => foo
[score] => 3
)
[1] => Array
(
[name] => bar
[score] => 1
)
)
I know there are other questions that sort multidimensional arrays, but I'm not able to find one that sums one of the sub values along the way.
You can use array_reduce
$arr = array(
array('name' => 'foo','score' => 1),
array('name' => 'foo','score' => 2),
array('name' => 'bar','score' => 1));
$array = array_reduce($arr, function ($a, $b) {
isset($a[$b['name']]['score']) ? $a[$b['name']]['score'] += $b['score'] : $a[$b['name']] = $b;
return $a;
});
var_dump($array);
Output
array
'foo' =>
array
'name' => string 'foo' (length=3)
'score' => int 3
'bar' =>
array
'name' => string 'bar' (length=3)
'score' => int 1

Which PHP Array function should I use?

I have two arrays:
Array
(
[0] => Array
(
[id] => 1
[type] => field
[remote_name] => Title
[my_name] => title
[default_value] => http%3A%2F%2Ftest.com
)
[1] => Array
(
[id] => 2
[type] => field
[remote_name] => BookType
[my_name] => book-type
[default_value] =>
)
[2] => Array
(
[id] => 3
[type] => value
[remote_name] => dvd-disc
[my_name] => dvd
[default_value] =>
)
)
Array
(
[title] => Test
[book-type] => dvd
)
I need to take each key in the second array, match it with the my_name value in the first array and replace it with the corresponding remote_name value of the first array while preserving the value of the second array.
There's got to be some carrayzy function to help!
EDIT: There will also be a few cases that the value of the second array will need to be replaced by the value of the first array's remote_name where the value of the second array matches the value of the first array's my_name. How can I achieve this?
EG: book-type => dvd should turn into BookType => dvd-disc
Like so?:
$first = array(
array(
'id' => 1,
'type' => 'field',
'remote_name' => 'Title',
'my_name' => 'title',
'default_value' => 'http%3A%2F%2Ftest.com',
),
array(
'id' => 2,
'type' => 'field',
'remote_name' => 'BookType',
'my_name' => 'book-type',
'default_value' => '',
),
array(
'id' => 3,
'type' => 'value',
'remote_name' => 'dvd-disc',
'my_name' => 'dvd',
'default_value' => '',
),
);
$second = array(
'title' => 'Test',
'book-type' => 'dvd',
);
$map = array('fields' => array(), 'values' => array());
foreach ($first as $entry) {
switch ($entry['type']) {
case 'field':
$map['fields'][$entry['my_name']] = $entry['remote_name'];
break;
case 'value':
$map['values'][$entry['my_name']] = $entry['remote_name'];
break;
}
}
$new = array();
foreach ($second as $key => $val) {
$new[isset($map['fields'][$key]) ? $map['fields'][$key] : $key] = isset($map['values'][$val]) ? $map['values'][$val] : $val;
}
print_r($new);
Output:
Array
(
[Title] => Test
[BookType] => dvd-disc
)
Explanation:
The first loop collects the my_name/remote_name pairs for fields and values and makes them more accessible.
Like so:
Array
(
[fields] => Array
(
[title] => Title
[book-type] => BookType
)
[values] => Array
(
[dvd] => dvd-disc
)
)
The second loop will traverse $second and use the key/value pairs therein to populate $new. But while doing so will check for key/value duplicates in $map.
Keys or values not found in the map will be used as is.
foreach($arr1 as &$el) {
$el['remote_name'] = $arr2[$el['my_name']];
}
unset($el);
I am not aware of such a carrayzy function, but I know how you could do it:
//$array1 is first array, $array2 is second array
foreach($array1 as $key => $value){
if (isset($value['remote_name'], $value['my_name']) && $value['remote_name'] && $value['my_name']){
$my_name = $value['my_name'];
if (isset($array2[$my_name])) {
$remote_name = $value['remote_name'];
$array2[$remote_name] = $array2[$my_name];
//cleanup
unset($array2[$my_name]);
}
}
}

Categories