PHP multidimensional array search with provided array column (using PHP5 array_column) - php

I need help with array search. The array example is:
$users=Array
(
0 => Array
(
'id' => 111,
'name' => 'Sandra Shush',
'sources' => '1234,678,780'
),
1 => Array
(
'id' => 112,
'name' => 'Stefanie Mcmohn',
'sources' => '32,99,85'
),
2 => Array
(
'id' => 113,,
'name' => 'Michael',
'sources' => '896,1213,1918'
),
3 => Array
(
'id' => 113,,
'name' => 'Michael',
'sources' => '72'
)
);
I need to extract the key from the provided array above, where the "sources" key matches the search string (integer).
I've tried with:
$key = array_search('99', array_column( $users, 'sources') ); // false
But of course, there's no chance to retrieve the key with this method. It only works if source key has only one value, for example:
$key = array_search('72', array_column( $users, 'sources') ); // 3
Is there a way to achieve this?
Thank you

Simply use foreach loop along with preg_match like as
$result = [];
foreach($users as $key => $value){
if(preg_match("/\b99\b/",$value['sources']) !== false){
$result[] = $key;
}
}
print_r($result);
Output:
Array
(
[0] => 1
)
Demo

Related

Search and get Key in Multidimensional Array

I have multidimensional array and I need to search for top level key by the value in "add_fields" arrays by "value". I cannot figure out I can achieve the result. Can somebody help me?
I was googling it and found several solutions but I was not able to get any result.
Trying this code
array_search('001001', array_column(array_column($arr, "usr_column_504"), 0)),
but didn't get anything and I need to get top level key. In this example its 0;
array (
0 =>
array (
'id' => 1,
'group_id' => 327,
'volume' => 0,
'vat' => 1,
'order_id' => 1,
'add_fields' =>
array (
1 =>
array (
'field' => 'usr_column_501',
'value' => '',
),
2 =>
array (
'field' => 'usr_column_504',
'value' => '001001',
),
),
),
1 =>
array (
'id' => 2,
'group_id' => 327,
'vat' => 1,
'order_id' => 2,
'add_fields' =>
array (
1 =>
array (
'field' => 'usr_column_501',
'value' => '',
),
2 =>
array (
'field' => 'usr_column_504',
'value' => '001002',
),
),
),
)
If you want the first key where the value of field equals usr_column_504 you could use an outer and an inner foreach.
When the value of field is found, return the $key from the outer foreach.
foreach ($arr as $key => $item) {
foreach ($item["add_fields"] as $addField) {
if ($addField["field"] === "usr_column_504") {
echo $key;
return;
}
}
}
Output
0
Php demo

Inserting a new key if a particular key value matches in both the arrays

$array1 = array(
[0] => array(
'id' => 'gdye6378399sjwui39',
'name' => 'Plate 1'
),
[1] => array(
'id' => 'xyz6378399sjwui39',
'name' => 'Plate 2'
),
[2] => array(
'id' => 'tr2e6378399sjwui39',
'name' => 'Plate 3'
)
)
and another array
$array2 = array(
[0] => array(
'id' => 'gdye6378399sjwui39',
'ETA' => '8'
),
[1] => array(
'id' => 'tr2e6378399sjwui39',
'ETA' => '9'
)
[2] => array(
'id' => 'xyz6378399sjwui39',
'ETA' => '5'
)
)
I want to compare the two arrays. I am doing it like this way:-
if(!empty($array2))
{
foreach($array1 as $ck => $cl)
{
foreach($array12 as $ued){
if($cl['id'] == $ued['id'])
{
$array1[$ck]['ETA'] = $ued['ETA'];
break;
}
}
}
What are the other better ways to do this? The order of the two arrays may vary, and so does the size.
If you index the second array by the id (using array_column()) you can get away without using the inner foreach() and just use isset()...
$match = array_column($array2, null, 'id');
foreach ( $array1 as $ck=>$cl) {
if ( isset($match[$cl['id']]) ) {
$array1[$ck]['ETA'] = $match[$cl['id']]['ETA'];
}
}
print_r($array1);

If array value is repeated in another array, combine both arrays

I have several arrays that I want to check for a repeated value and if the value is found to be repeated in one of the other arrays, then combine both of those arrays together.
I give an example below of 2 arrays that have repeated values.
example: the value in purchase_order_number is the same in both arrays below. They are not unique values. But the values in tracking_number are unique.
I want to check if the value in purchase_order_number is repeated in another array. If the same value is found in another array, then combine both of those arrays into 1 array.
I'm trying to get the value in tracking_number and service combined into a single array when the value in purchase_order_number is the same in 2 or more arrays.
Example arrays below.
not combined
array (
'data' =>
array (
15 =>
array (
'type' => 'Tracking',
'id' => 2830143,
'attributes' =>
array (
'tracking_number' => '1Z5270560360309870',
'service' => 'UPS',
'order_id' => 2606218,
'purchase_order_number' => '7249491',
'recipient_attempts' => 1,
),
),
16 =>
array (
'type' => 'Tracking',
'id' => 2830144,
'attributes' =>
array (
'tracking_number' => '1Z5270560361740866',
'service' => 'UPS',
'order_id' => 2606218,
'purchase_order_number' => '7249491',
'recipient_attempts' => 1,
),
),
),
)
Example given below of how I need to combine the two above arrays.
Combined
array (
'data' =>
array (
16 =>
array (
'type' => 'Tracking',
'id' => 2830144,
'attributes' =>
array (
'tracking' =>
array (
0 =>
array (
'tracking_number' => '1Z5270560360309870',
'service' => 'UPS',
),
1 =>
array (
'tracking_number' => '1Z5270560361740866',
'service' => 'UPS',
),
),
'order_id' => 2606218,
'purchase_order_number' => '7249491',
'recipient_attempts' => 1,
),
),
),
)
Here's a reduce based solution with caveats:
$arr['data'] = array_reduce($arr['data'], function ($out, $item) {
// keys we want to extract
static $tracking_keys = ['tracking_number' => '', 'service' => ''];
// yank tracking keys from attributes
$tracking = array_intersect_key($item['attributes'], $tracking_keys);
$item['attributes'] = array_diff_key($item['attributes'], $tracking_keys);
// insert to new array based on order number
$order_no = $item['attributes']['purchase_order_number'];
if (!isset($out[$order_no])) {
$item['attributes']['tracking'] = [$tracking];
$out[$order_no] = $item;
} else {
array_push($out[$order_no]['attributes']['tracking'], $tracking);
}
return $out;
}, []);
Keys in 'data' are not retained and 'id' is set by the first item.

Change index of an array

I want to change the index of an array but I don't know how to do it..
The following array
array(
0 => array ( 'id' => 33, 'name' => 'test' )
1 => array ( 'id' => 37, 'name' => 'test2' )
)
should become - if i want the index
array(
33 => array ( 'id' => 33, 'name' => 'test' )
37 => array ( 'id' => 37, 'name' => 'test2' )
)
or if i want the name
array(
test => array ( 'id' => 33, 'name' => 'test' )
test2 => array ( 'id' => 37, 'name' => 'test2' )
)
also for a multi-dimensional array
array(
0 => array ( 'id' => 33, 'details' => array (name => 'test' , age ='50' ) )
1 => array ( 'id' => 37, 'details' => array (name => 'test2' , age ='60' ) )
)
to index replace 0 and 1 with the name - test or test2
right now I made a function but is not working with multi dimensional arrays
function index_array( $array, $index ){
$new_array = array();
foreach($array as $key => $value){
$new_array[$index] = $array[$key];
}
return $new_array;
}
$array = array(33 => $oldarray[0], 37 => $oldarray[1]);
$array = array('test' => $oldarray[0], 'test2' => $oldarray[1]);
Since the right-hand-side of the expression is evaluated before the assignment you could also use $array on both sides instead of a different variable name.
I'd do it with a mapping table for the first part, or a simple foreach for the second part:
<?php
$arr = array(
0 => array( 'id' => 33, 'name' => 'test' ),
1 => array( 'id' => 37, 'name' => 'test2' )
);
/* Convert to other indexes */
$mapping = array(
0 => 33,
1 => 37
);
foreach($arr as $k => $v){
unset($arr[$k]);
$arr[$mapping[$k]] = $v;
}
print_r($arr);
/* Convert key to name field */
foreach($arr as $k => $v){
unset($arr[$k]);
$arr[$v['name']] = $v;
}
print_r($arr);
EDIT: Now that I read your question again, the first part is actually the same as the second, but then just with the id field instead of the name field.
EDIT2: Note that you'd have to use another array to write to, to avoid overrides, which will occur when the id field is used as a replacement.

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