Extract arrays with string to a new array - php

I know that there are some posts at SO with a similar issue, but none of those could really help me solving mine. I do have the following $test array:
array(1) {
[0]=>
array(4) {
[0]=>
array(2) {
["id"]=>
string(8) "40265656"
["text"]=>
string(29) "10' - 1st Corner - Terengganu"
}
[1]=>
array(2) {
["id"]=>
string(8) "40265715"
["text"]=>
string(25) "18' - 2nd Corner - Pahang"
}
[2]=>
array(2) {
["id"]=>
string(8) "40265770"
["text"]=>
string(29) "23' - 3rd Corner - Terengganu"
}
[3]=>
array(3) {
["id"]=>
string(8) "40265830"
["text"]=>
string(29) "26' - 4th Corner - Pahang"
}
}
}
and would like to extract only those arrays containing Pahang in the ["text"] key. First I have tried
$key = array_search('Pahang', $test);
and that gives me bool(false). What am I doing wrong here?

I think this way will be right:
$result = [];
foreach ($array[0] as $arr) {
if (strpos($arr['text'], "Pahang") !== false) {
$result[] = $arr;
}
}

The function array_search(...) searches for a value inside an array, but your array is not flat, it's multidimensional, this means you have one or more arrays inside another array.
In your case, you can use array_filter(...) that allows you to filter your array elements in a callable function.
So, initially you have to define a function that filters the elements:
function getPahang($element) {
return $element['text'] === 'Pahang'
}
This function returns true when the element text value is equal to 'Pahang', instead it returns false.
Now, you have to call array_filter, by passing your array and the callable function:
$new_array = array_filter($test[0], 'getPahang');
You can try a similar script here: http://sandbox.onlinephpfunctions.com/code/c076222dd6d1c6f2675d0241742e6c11da6eff53

Related

Putting Array with same values into another array?

I have one big array which has a load of similar values but I want to put all the arrays with the same value into another array. For example, I have this array.
array(4) {
[0]=>
array(8) {
["symbol"]=>
string(3) "aaaa"
["name"]=>
string(7) "aaaa"
["buy_price"]=>
string(14) "100.0000000000"
["current_worth"]=>
string(14) "100.2500000000"
}
[3]=>
array(8) {
["symbol"]=>
string(3) "aaa"
["name"]=>
string(7) "aaaaa"
["buy_price"]=>
string(14) "100.0000000000"
["current_worth"]=>
string(14) "100.2500000000"
}
[2]=>
array(8) {
["symbol"]=>
string(3) "xxx"
["name"]=>
string(7) "xxxxx"
["buy_price"]=>
string(14) "100.0000000000"
["current_worth"]=>
string(14) "100.2500000000"
}
}
I want to be able run this array through a foreach loop and then output the array results together that all have the same name. Like too
Name aaa
-- Name aaa [0]
-- Name aaa [1]
Name xxx
-- Name xxx [0]
I am struggling how to do the logic.
If I understand correctly, you need some reducing. Assuming that $origin_array contain what you need to transform:
$result = array_reduce($origin_array, function ($carry, $item) {
$name = $item['name'];
$carry[$name][] = $item;
return $carry;
}, []);
This code will make 2-dimensional array where elements grouped by name field of origin array.
Explanation
The best explanation will be to write analogical foreach loop:
$my_reduce = function ($carry, $item) { // callback, 2-nd param
$name = $item['name'];
$carry[$name][] = $item;
return $carry;
};
$result = []; // initial value, 3 param
foreach($origin_array as $item) {
$result = $my_reduce($result, $item);
}
This is roughly speaking what happens under the hood of array_reduce function.

How to access third level value in multidimensional mixed associative and numeric array

I am working with the array below and wish to ask how should I access/reference values in 'match_id' and 'match_comp_ID'?
I need to reference it in two ways: Question 1: firstly in a foreach statement. This has been answered below:
foreach $jason_a['matches'] as $match {
echo $match['match_id']
echo $match['match_comp_id']
}
Question 2: I want to sort the output from the above by those same two keys by using a sort function which I will call via usort:
function cmp($a, $b)
{
// sort by match_id
$retval = strnatcmp(substr($b->match_id,0,10), substr($a->match_id,0,10));
// if identical, sort by match_comp_id
if(!$retval) $retval = strnatcmp($a->match_comp_id, $b->match_comp_id);
return $retval;
}
usort($json_a, "cmp");
Using match_id or $json['match_id] format in the sort function don't work. I am at a loss to know what to search for.
Array is:
array(4) {
["APIRequestsRemaining"]=> int(920)
["matches"]=> array(3) {
[0]=> array(3) {
["match_id"]=> string(7) "1999477"
["match_static_id"]=> string(7) "1755895"
["match_comp_id"]=> string(4) "1204" }
[1]=> array(3) {
["match_id"]=> string(7) "1999478"
["match_static_id"]=> string(7) "1755891"
["match_comp_id"]=> string(4) "1204" }
[2]=> array(3) {
["match_id"]=> string(7) "1999479"
["match_static_id"]=> string(7) "1755894"
["match_comp_id"]=> string(4) "1204" }
}
["Action"]=> string(5) "today"
["Params"]=> array(4) {
["Action"]=> string(5) "today"
["APIKey"]=> string(31) "xxxx-xxxx-xxxx-xxxx"
["OutputType"]=> string(4) "JSON"
["comp_id"]=> string(4) "1204"
}
The php manual states:
Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type. I think this is my problem. But if arrays cannot be used as keys, then how do I access this key-value?
foreach ($json_a['matches'] as $match) {
// do something with $match['match_id'] and $match['match_comp_id']
}
For part 2 of your question, you really want to pass the 'matches' sub-array to your sort function:
$matches = $json_a['matches'];
usort($matches, 'cmp');
// now the $matches array should be sorted according to rules in function cmp()

Comparing arrays in PHP - which order - string conversion errors

I var_dumped two arrays, the top on is the array coming in, $new_array, while the other one is a preexisting array $current_array:
// New Array
array(3) {
["Contributor"]=>
array(2) {
[0]=>
string(13) "edit_carousel"
[1]=>
string(13) "read_carousel"
}
["Editor"]=>
array(1) {
[0]=>
string(16) "delete_mini_feed"
}
["Author"]=>
array(3) {
[0]=>
string(11) "edit_blocks"
[1]=>
string(12) "edit_blockss"
[2]=>
string(12) "edit_blockss"
}
}
// Preexisting
array(3) {
["Contributor"]=>
array(2) {
[0]=>
string(13) "edit_carousel"
[1]=>
string(13) "read_carousel"
}
["Editor"]=>
array(4) {
[0]=>
string(16) "delete_mini_feed"
[1]=>
string(15) "edit_mini_feeds"
[2]=>
string(23) "edit_private_mini_feeds"
[3]=>
string(15) "edit_mini_feeds"
}
["Author"]=>
array(3) {
[0]=>
string(11) "edit_blocks"
[1]=>
string(12) "edit_blockss"
[2]=>
string(12) "edit_blockss"
}
}
I am trying to do something like: var_dump(array_intersect_assoc($current_array, $new_array)); to see whats different in the current array as opposed to the new array and generate an array of "differences" keeping the structure intact.
The issue is:
Is the order of arrays to be compared right? compare old to new and get an array of whats different in old. or should it be compare new to old?
Doing this, results in: Array to string conversion notice, but also prints out an array which is below.
I cant tell if these are: "these are whats not in old, but in new" or "the are whats not in new but in old" .... (It should say: these are not whats in old but in new).
array(3) {
["Contributor"]=>
array(2) {
[0]=>
string(13) "edit_carousel"
[1]=>
string(13) "read_carousel"
}
["Editor"]=>
array(4) {
[0]=>
string(16) "delete_mini_feed"
[1]=>
string(15) "edit_mini_feeds"
[2]=>
string(23) "edit_private_mini_feeds"
[3]=>
string(15) "edit_mini_feeds"
}
["Author"]=>
array(3) {
[0]=>
string(11) "edit_blocks"
[1]=>
string(12) "edit_blockss"
[2]=>
string(12) "edit_blockss"
}
}
The php function array_intersect_assoc() should return everything in the first array (aka $current_array) that exists in the second array (aka $new_array).
The issue that you are running into is that array_intersect_assoc() doesn't preform the key comparison recursively. It's only comparing the first level of keys (Contributor, Editor and Author).
Here's more information about the recursive issue. PHP Question: how to array_intersect_assoc() recursively
Your problem is that you are trying to perform array_intersect on a multidimensional array, but the function does string comparison of elements, resulting in array to string conversion error.
As you have the same keys in both arrays, the simplest solution is just to foreach through and to compare subsequent arrays(and you rather need array_diff if you want difference between the elements)
foreach($array_1 as $index => $sub_array) {
$sub_array_2 = $array_2[$index];
$diff = array_diff($sub_array, $sub_array_2);
// do something with diff
}
UPDATE
If You want to get everything that's not in array_1 but in array_2:
$result = [];
# lets find if there's any new elements
$keys_1 = array_keys($array_1);
$keys_2 = array_keys($array_2);
$diff = array_diff($keys_1, $keys_2);
if(!empty($diff)) {
foreach($diff as $key) {
if(isset($array_2[$key])) {
# it's in array_2
$result[$key] = $array_2[$key];
}
}
}
# now get difference between shared elements
$intersection = array_intersect($keys_1, $keys_2);
foreach($intersection as $key) {
$element_1 = $array_1[$key];
$element_2 = $array_2[$key];
$diff = array_diff($element_1, $element_2);
if(sizeof($diff)) {
if(!isset($result[$key]) ||!is_array($result[$key]) ) {
$result[$key] = array($diff);
} else {
$result[$key][] = $diff;
}
}
}

Array_Intersect not working as expected

I have two multidemensional arrays and I am trying to use array_intersect to find the values from $array1 that occur in $array2. Instead the results, as you can see below, include both values from the first array $array1 even though only one of the values occurs in the second array $array2. I suppose I have some misunderstanding of how this function works, can anyone clarify what I am doing wrong here?
var_dump($array1);
array(2) {
[0]=>
array(1) {
["id"]=>
string(2) "28"
}
[7]=>
array(1) {
["id"]=>
string(2) "30"
}
}
var_dump($array2);
array(1) {
[0]=>
array(1) {
["id"]=>
string(2) "30"
}
}
var_dump(array_intersect($array1, $array2));
array(2) {
[0]=>
array(1) {
["id"]=>
string(2) "28"
}
[7]=>
array(1) {
["id"]=>
string(2) "30"
}
}
The function array_intersect compares the values as strings, see manual. Unfortunately, this gives simply "Array" for all arrays.
Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation
is the same.
Instead you can use a custom compare function:
array_uintersect($array1, $array2, function($a, $b) { return ($a<$b)?-1:($a==$b)?0:1; })
Or use !== if you want to also compare order and types - see here for the difference.
array_intersect_assoc() looks at key and value for intersection.

php array cut dimensions (return single 'row')

Is it possible to cut multiple dimensions in a php array?
example:
I want the 4th dimension of each first-level element
array(1) {
[0]=> array(5)
{
[0]=> string(_) "/opt/path [10823] (/home/path/file.xml)"
[1]=> string(_) "/opt/path"
[2]=> string(_) "10823"
[3]=> string(_) "(/home/path/file.xml)"
[4]=> string(_) "/home/path/file.xml"
}
}
=>
array(1){ ( [0]=> string(_) "/home/path/file.xml") }
is there an internal php function or a way to achieve this without a loop?
Use array_map :
function selectMyLine($line) {
return $line[4];
}
$result = array_map("selectMyLine", $data);
print_r($result);
You could alse do the same with array_walk, which directly edit your array instead of creating a new one.

Categories