How to check two array in php [duplicate] - php

This question already has an answer here:
Recursive search in PHP array with path
(1 answer)
Closed 3 years ago.
here i am having two array below the structure
$a = [
"100" => ["name" => "1 A"],
"200" => ["name" => "1 B"],
"300" => ["name" => "1 C"],
"400" => ["name" => "1 D"],
];
$b = [
"user1" => ["100" , "200"],
"user2" => ["100" , "300"],
"user3" => ["100" , "200","400"],
];
Now lets take example $b user1 having the value of 100 & 200 , now want to check the value from $a 100 means what the name, 200 means what is the name ?
as per my array records 100 means value is "name" => "1 A" & 200 is "name" => "1 B"
My expected answer
Array
(
[user1] => Array
(
[0] => 1 A
[1] => 1 B
)
[user2] => Array
(
[0] => 1 A
[1] => 1 C
)
[user3] => Array
(
[0] => 1 A
[1] => 1 B
[2] => 1 D
)
)

You can use foreach
$r = [];
foreach($activeGroups as $k => $v){
foreach($v as $ik => $iv){
$r[$k][] = $teacherActiveGroupNameData[$iv]['name'];
}
}
https://3v4l.org/vnUtc

array_walk() and array_map() might help you. array_walk() is to make an iteration over $activeGroups array and array_map() is for extracting name from $teacherActiveGroupNameData array.
array_walk($activeGroups, function (&$val) use ($teacherActiveGroupNameData) {
$val = array_map(function ($val) use ($teacherActiveGroupNameData) {
return $teacherActiveGroupNameData[$val]['name'];
}, $val);
});
echo '<pre>', print_r($activeGroups);
Working demo.

Related

How to count specific value from array PHP?

I have an multidimensional array and I need to count their specific value
Array
(
[0] => Array
(
[Report] => Array
(
[id] => 10
[channel] => 1
)
)
[1] => Array
(
[Report] => Array
(
[id] => 92
[channel] => 0
)
)
[2] => Array
(
[Report] => Array
(
[id] => 18
[channel] => 0
)
)
[n] => Array
)
I need to get output like that: channel_1 = 1; channel_0 = 2 etc
I made a function with foreach:
foreach ($array as $item) {
echo $item['Report']['channel'];
}
and I get: 1 0 0 ... but how can I count it like: channel_1 = 1; channel_0 = 2, channel_n = n etc?
Try this. See comments for step-by-step explanation.
Outputs:
array(2) {
["channel_1"]=>
int(1)
["channel_0"]=>
int(2)
}
Code:
<?php
// Your input array.
$a =
[
[
'Report' =>
[
'id' => 10,
'channel' => 1
]
],
[
'Report' =>
[
'id' => 92,
'channel' => 0
]
],
[
'Report' =>
[
'id' => 18,
'channel' => 0
]
]
];
// Output array will hold channel_N => count pairs
$result = [];
// Loop over all reports
foreach ($a as $report => $values)
{
// Key takes form of channel_ + channel number
$key = "channel_{$values['Report']['channel']}";
if (!isset($result[$key]))
// New? Count 1 item to start.
$result[$key] = 1;
else
// Already seen this, add one to counter.
$result[$key]++;
}
var_dump($result);
/*
Output:
array(2) {
["channel_1"]=>
int(1)
["channel_0"]=>
int(2)
}
*/
You can easily do this without a loop using array_column() and array_count_values().
$reports = array_column($array, 'Report');
$channels = array_column($reports, 'channel');
$counts = array_count_values($channels);
$counts will now equal an array where the key is the channel, and the value is the count.
Array
(
[1] => 1
[0] => 2
)

How can I map two arrays based on specific indexes?

Array1 ( [0] => [1] => [2] => 3 [3] => [4] => 5 [5] => [6] => )
Array2 ( [0] => URD [1] => ISL )
I want to map $array2 values to $array1 indexes (those having values 3 and 5) and I want get an array like this:
Array ( [0] => [1] => [2] => URD [3] => [4] => ISL [5] => [6] => )
I have tried the following:
$newArray = array_values(array_filter(array_merge($array1,$array2)));
but the actual result is:
Array([0] => 3[1] => 5[2] => URD[3] => ISL)
The expected result should be:
Array ( [0] => [1] => [2] => URD [3] => [4] => ISL [5] => [6] => )
Code
Try the following:
<?php
$array1 = ["", "", "3", "", "5", "", ""];
$array2 = ["URD", "ISL"];
foreach($array1 as $id => $a1){
//for each item in array 1
if($a1){
//if the array 1 item has a value
$array1[$id] = array_shift($array2);
//replace it with an item from array 2
}
if(empty($array2)){
//if there are no more values left to share in array 2, stop
break;
}
}
var_dump($array1);
Output
array(7) {
[0]=>
string(0) ""
[1]=>
string(0) ""
[2]=>
string(3) "URD"
[3]=>
string(0) ""
[4]=>
string(3) "ISL"
[5]=>
string(0) ""
[6]=>
string(0) ""
}
Caveats
The method assumes that there will be values in both array 1 and array 2.
Once the values in array 2 have been split out and array 2 is empty, array 1 items with set values will no longer be affected.
The method does not care what the value set in array 1 is, just that there is a value.
Further reading
foreach()
array_shift()
Codepen
https://3v4l.org/RDQY6
This solution works and simple to understands as OPS requested...
<?
$array1 = ["", "", "3", "", "5", "", ""];
$array2 = ["URD", "ISL"];
$i =0;
foreach($array1 as $keys=>$values) {
if($values == 3 || $values ==5) {
if(isset($array2[$i])){
$array1[$keys] = $array2[$i];
$i++;
}else { break; }
}
}
print_R($array1);
?>
it will replace the array2 values from array 1 values wherever 5 & 3 will come and which is independent of their sorting order.
example
$array1 = ["5", "", "3", "", "", "", ""]; will be converted into
$array1 = ["URD", "" ,"ISL","","",""];
if you want it in order like 3 should always come first then first sort array1 then use my code...
if you want 3 should be replace by URD and 5 should be replace by ISL
then you if codition will be different
Just another way to do it... (untested, but it should work)
<?php
$a = array ( 0 => '', 1 => '', 2 => 3, 3 => '', 4 => 5, 5 => '', 6 => '' );
$b = array ( 0 => 'URD', 1 => 'ISL' );
$c = array_replace ( $a, array_combine ( array_keys ( array_filter ( $a ) ), $b ) );
print_r ( $c );
?>

Sort multidimensional array by keys - fails on duplicates [duplicate]

This question already has answers here:
Sort multi-dimensional array by specific key
(6 answers)
Closed 7 years ago.
I have a function sortBy() that I use to sort multidimensional arrays by a particular key. Here is a sample array:
Array
(
[0] => Array
(
[id] => 4
[type] => 1
[game] => 1
[platform] => 0
[TotalPot] => 7550
)
[1] => Array
(
[id] => 5
[type] => 0
[game] => 2
[platform] => 0
[TotalPot] => 7500
)
)
Here is the function
function sortBy($arr, $field='id', $order=1) {
$a = array();
if ( !is_array($arr) )
return false;
foreach($arr as $subArr) {
$a[$subArr[$field]] = $subArr;
}
if ( $order == 1 ) sort($a);
else rsort($a);
return $a;
}
In this case, calling sortBy($array, 'TotalPot'); would work fine, because the two values for TotalPot are different. However, if you run this example and set both TotalPot fields to $7500, it overwrites the first occurrence with the latter.
What would be the best way to make this function allow for two items with the same value but still keep them in relevant order? I thought about adding another character, an A or 1 to the end, but this seems sloppy and not very predictable, so a better course of action would be greatly appreciated.
You can simplify your code and just use usort(), e.g.
function sortArrayByField(array &$arr, $field = "id", $ASC = TRUE) {
usort($arr, function($a, $b)use($field, $ASC){
if($a[$field] == $b[$field])
return 0;
return $a[$field] > $b[$field] ? $ASC : !$ASC;
});
}
Then just call it like this:
sortArrayByField($array, "TotalPot", TRUE);
print_r($array);
The reason they are getting overwritten is because you're creating an array where the index is the value of the totalPot.
If there are duplicates, then you will only have one array element with the totalPot.
Easiest way is just to usort this:
<?php
$array = [
[
"id" => 4,
"type" => 1,
"game" => 1,
"platform" => 0,
"TotalPot" => 7550
], [
"id" => 5,
"type" => 0,
"game" => 2,
"platform" => 0,
"TotalPot" => 7500
]
];
usort($array, function($a, $b) {
return $a['TotalPot'] - $b['TotalPot'];
});
print_r($array);
Output:
Array
(
[0] => Array
(
[id] => 5
[type] => 0
[game] => 2
[platform] => 0
[TotalPot] => 7500
)
[1] => Array
(
[id] => 4
[type] => 1
[game] => 1
[platform] => 0
[TotalPot] => 7550
)
)
You can also make this a function:
function sortBy($arr, $field='id', $order=1) {
usort($arr, function($a, $b) use ($field, $order) {
if ($order == 1)
return $a[$field] - $b[$field];
else
return $b[$field] - $a[$field];
});
}

how to get value from associative array

This is my array :
Array
(
[0] => Array
(
[0] => S No.
[1] => Contact Message
[2] => Name
[3] => Contact Number
[4] => Email ID
)
[1] => Array
(
[0] => 1
[1] => I am interested in your property. Please get in touch with me.
[2] => lopa <br/>(Individual)
[3] => 1234567890
[4] => loperea.ray#Gmail.com
)
[2] => Array
(
[0] => 2
[1] => This user is looking for 3 BHK Multistorey Apartment for Sale in Sohna, Gurgaon and has viewed your contact details.
[2] => shiva <br/>(Individual)
[3] => 2135467890
[4] => sauron82#yahoo.co.in
)
)
How can I retrieve all data element wise?
You can get information about arrays in PHP on the official PHP doc page
You can access arrays using square braces surrounding the key you like to select [key].
So $array[1] will give yoo:
Array
(
[0] => 1
[1] => I am interested in your property. Please get in touch with me.
[2] => lopa <br/>(Individual)
[3] => 1234567890
[4] => loperea.ray#Gmail.com
)
And $array[1][2] will give you:
lopa <br/>(Individual)
Or you can walkt through the elements of an array using loops like the foreach or the for loop.
// perfect for assoc arrays
foreach($array as $key => $element) {
var_dump($key, $element);
}
// alternative for arrays with seamless numeric keys
$elementsCount = count($array);
for($i = 0; $i < $elementsCount; ++$i) {
var_dump($array[$i]);
}
You have integer indexed elements in multidimensional array. To access single element from array, use array name and it's index $myArray[1]. To get inner element of that previous selected array, use second set of [index] - $myArray[1][5] and so on.
To dynamically get all elements from array, use nested foreach loop:
foreach ($myArray as $key => $values) {
foreach ($values as $innerKey => $value) {
echo $value;
// OR
echo $myArray[$key][$innerKey];
}
}
The solution is to use array_reduce:
$header = array_map(
function() { return []; },
array_flip( array_shift( $array ) )
); // headers
array_reduce( $array , function ($carry, $item) {
$i = 0;
foreach( $carry as $k => $v ) {
$carry[$k][] = $item[$i++];
}
return $carry;
}, $header );
First of all we get the header from the very first element of input array. Then we map-reduce the input.
That gives:
$array = [['A', 'B', 'C'], ['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'], ['a3', 'b3', 'c3']];
/*
array(3) {
'A' =>
array(3) {
[0] =>
string(2) "a1"
[1] =>
string(2) "a2"
[2] =>
string(2) "a3"
}
'B' =>
array(3) {
[0] =>
string(2) "b1"
[1] =>
string(2) "b2"
[2] =>
string(2) "b3"
}
'C' =>
array(3) {
[0] =>
string(2) "c1"
[1] =>
string(2) "c2"
[2] =>
string(2) "c3"
}
}
*/
I think this is what you are looking for
$array = Array
(
0=> Array
(
0 => 'S No.',
1 => 'Contact Message',
2 => 'Name',
3 => 'Contact Number',
4 => 'Email ID'
),
1 => Array
(
0 => 1,
1 => 'I am interested in your property. Please get in touch with me.',
2 => 'lopa <br/>(Individual)',
3 => '1234567890',
4 => 'loperea.ray#Gmail.com',
),
2 => Array
(
0 => 2,
1 => 'This user is looking for 3 BHK Multistorey Apartment for Sale in Sohna, Gurgaon and has viewed your contact details.',
2 => 'shiva <br/>(Individual)',
3 => '2135467890',
4 => 'sauron82#yahoo.co.in',
)
);
$result_array = array();
array_shift($array);
reset($array);
foreach($array as $x=>$array2){
foreach($array2 as $i => $arr){
if($i == 1){
$result_array[$x]['Contact Message'] = $arr;
}elseif($i == 2){
$result_array[$x]['Name'] = $arr;
}elseif($i == 3){
$result_array[$x]['Contact Number'] =$arr;
}elseif($i == 4){
$result_array[$x]['Email ID'] = $arr;
}
}
}
print_r($result_array);

How do I use array_unique on an array of arrays?

I have an array
Array(
[0] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
[1] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
[2] => Array
(
[0] => 33
[user_id] => 33
[1] => 8
[frame_id] => 8
)
[3] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
[4] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
)
As you can see key 0 is the same as 1, 3 and 4. And key 2 is different from them all.
When running the array_unique function on them, the only left is
Array (
[0] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
)
Any ideas why array_unique isn't working as expected?
It's because array_unique compares items using a string comparison. From the docs:
Note: Two elements are considered
equal if and only if (string) $elem1
=== (string) $elem2. In words: when the string representation is the same.
The first element will be used.
The string representation of an array is simply the word Array, no matter what its contents are.
You can do what you want to do by using the following:
$arr = array(
array('user_id' => 33, 'frame_id' => 3),
array('user_id' => 33, 'frame_id' => 3),
array('user_id' => 33, 'frame_id' => 8)
);
$arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr)));
//result:
array
0 =>
array
'user_id' => int 33
'user' => int 3
2 =>
array
'user_id' => int 33
'user' => int 8
Here's how it works:
Each array item is serialized. This
will be unique based on the array's
contents.
The results of this are run through array_unique,
so only arrays with unique
signatures are left.
array_intersect_key will take
the keys of the unique items from
the map/unique function (since the source array's keys are preserved) and pull
them out of your original source
array.
Here's an improved version of #ryeguy's answer:
<?php
$arr = array(
array('user_id' => 33, 'tmp_id' => 3),
array('user_id' => 33, 'tmp_id' => 4),
array('user_id' => 33, 'tmp_id' => 5)
);
# $arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr)));
$arr = array_intersect_key($arr, array_unique(array_map(function ($el) {
return $el['user_id'];
}, $arr)));
//result:
array
0 =>
array
'user_id' => int 33
'tmp_id' => int 3
First, it doesn't do unneeded serialization. Second, sometimes attributes may be different even so id is the same.
The trick here is that array_unique() preserves the keys:
$ php -r 'var_dump(array_unique([1, 2, 2, 3]));'
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[3]=>
int(3)
}
This let's array_intersect_key() leave the desired elements.
I've run into it with Google Places API. I was combining results of several requests with different type of objects (think tags). But I got duplicates, since an object may be put into several categories (types). And the method with serialize didn't work, since the attrs were different, namely, photo_reference and reference. Probably these are like temporary ids.
array_unique() only supports multi-dimensional arrays in PHP 5.2.9 and higher.
Instead, you can create a hash of the array and check it for unique-ness.
$hashes = array();
foreach($array as $val) {
$hashes[md5(serialize($val))] = $val;
}
array_unique($hashes);
array_unique deosn't work recursive, so it just thinks "this are all Arrays, let's kill all but one... here we go!"
Quick Answer (TL;DR)
Distinct values may be extracted from PHP Array of AssociativeArrays using foreach
This is a simplistic approach
Detailed Answer
Context
PHP 5.3
PHP Array of AssociativeArrays (tabluar composite data variable)
Alternate name for this composite variable is ArrayOfDictionary (AOD)
Problem
Scenario: DeveloperMarsher has a PHP tabular composite variable
DeveloperMarsher wishes to extract distinct values on a specific name-value pair
In the example below, DeveloperMarsher wishes to get rows for each distinct fname name-value pair
Solution
example01 ;; DeveloperMarsher starts with a tabluar data variable that looks like this
$aodtable = json_decode('[
{
"fname": "homer"
,"lname": "simpson"
},
{
"fname": "homer"
,"lname": "jackson"
},
{
"fname": "homer"
,"lname": "johnson"
},
{
"fname": "bart"
,"lname": "johnson"
},
{
"fname": "bart"
,"lname": "jackson"
},
{
"fname": "bart"
,"lname": "simpson"
},
{
"fname": "fred"
,"lname": "flintstone"
}
]',true);
example01 ;; DeveloperMarsher can extract distinct values with a foreach loop that tracks seen values
$sgfield = 'fname';
$bgnocase = true;
//
$targfield = $sgfield;
$ddseen = Array();
$vout = Array();
foreach ($aodtable as $datarow) {
if( (boolean) $bgnocase == true ){ #$datarow[$targfield] = #strtolower($datarow[$targfield]); }
if( (string) #$ddseen[ $datarow[$targfield] ] == '' ){
$rowout = array_intersect_key($datarow, array_flip(array_keys($datarow)));
$ddseen[ $datarow[$targfield] ] = $datarow[$targfield];
$vout[] = Array( $rowout );
}
}
//;;
print var_export( $vout, true );
Output result
array (
0 =>
array (
0 =>
array (
'fname' => 'homer',
'lname' => 'simpson',
),
),
1 =>
array (
0 =>
array (
'fname' => 'bart',
'lname' => 'johnson',
),
),
2 =>
array (
0 =>
array (
'fname' => 'fred',
'lname' => 'flintstone',
),
),
)
Pitfalls
This solution does not aggregate on fields that are not part of the DISTINCT operation
Arbitrary name-value pairs are returned from arbitrarily chosen distinct rows
Arbitrary sort order of output
Arbitrary handling of letter-case (is capital A distinct from lower-case a ?)
See also
php array_intersect_key
php array_flip
function array_unique_recursive($array)
{
$array = array_unique($array, SORT_REGULAR);
foreach ($array as $key => $elem) {
if (is_array($elem)) {
$array[$key] = array_unique_recursive($elem);
}
}
return $array;
}
Doesn't that do the trick ?
`
$arr = array(
array('user_id' => 33, 'tmp_id' => 3),
array('user_id' => 33, 'tmp_id' => 4),
array('user_id' => 33, 'tmp_id' => 3),
array('user_id' => 33, 'tmp_id' => 4),
);
$arr1 = array_unique($arr,SORT_REGULAR);
echo "<pre>";
print_r($arr1);
echo "</pre>";
Array(
[0] => Array(
[user_id] => 33
[tmp_id] => 3
)
[1] => Array(
[user_id] => 33
[tmp_id] => 4
)
)
`

Categories