Searching specific value in array - php

I have an array, and i want to find all values where correct => true:
$quiz_array = array (
'question1' => array (
'q1a1' => array (
'correct' => FALSE,
'answer' => 'false answer1'
),
'q1a2' => array (
'correct' => FALSE,
'answer' => 'false answer2'
),
'q1a3' => array (
'correct' => FALSE,
'answer' => 'false answer3'
),
'q1a4' => array (
'correct' => TRUE,
'answer' => 'correct answer'
)
)
);
I want to do a search, where it would return q1a4 in this case, because correct => TRUE. I trid using in_array and array_search but no luck. Any suggestions?

Here is your answer,
foreach($quiz_array as $key=> $value) {
foreach($quiz_array[$key] as $key=> $value) {
if( $value["correct"] ) {
echo $key ."<br>";
}
}
}

foreach ($quiz_array as $key => $value) {
if (strpos($value, '<name of value you want to search>') !== false) {
$new_key = $key;
break;
}
}

function correct($array) {
return $array('correct');
}
$results= array();
foreach($quiz_array as $key => $value) {
$correct= array_filter($value, 'correct');
$results[$key]= $correct;
}
print_r($results);

You could do something like this:
$correctAnswers = array();
foreach ($quiz_array as $question => $answers) {
$correctAnswers[$question] = array_filter($answers, function($v) {
return $v['correct'];
});
}
var_dump($correctAnswers); // array('question1' => array('q1a4' => array('correct' => true, 'answer' => 'correct answer')));
If you want to return just the correct answers key (eg. q1a41) you could do:
$correctAnswers = array();
foreach ($quiz_array as $question => $answers) {
foreach ($answers as $k => $a) {
if ($a['correct']) {
$correctAnswers[$question] = $k;
}
}
}
var_dump($correctAnswers); // array('question1' => 'q1a4');

Related

How can I convert `$arr['something1']['something2'] = value;` into `$arr['something1[something2]'] = value` in PHP?

I am stuck...
I have this value in my PHP:
$arr['something1']['something2'] = value;
I want to have a func($arr) that returns:
$arr['something1[something2]'] = value;
Here is my current codes for nested 3 arrays:
static function flattenArray(array $notFlat, string $pK) {
$index = 0;
foreach ($notFlat as $k => $v) {
if (is_array($v)) {
foreach ($v as $_k => $_v) {
if (is_array($_v)) {
foreach ($_v as $__k => $__v) {
if (is_array($__v)) {}
else{
unset($notFlat[$k]);
$newArray = array_slice($notFlat, 0, $index, true) +
$notFlat[$k] = [$pK.$k.'['.$_k.']'.'['.$__k.']' => $__v] +
array_slice($notFlat, $index, NULL, true);
$notFlat = $newArray;
}
}
}
}
}
$index ++;
}
return $notFlat;
}
But that is too manual... I think recursive function can work but I am not sure what to return in case iterated value is an array.
EDIT1: Expected Output
$asd = ['asd' => ['jkf' => ['qwe' => 'wer', 'asd' => '123', 'kjk' => 'sdf', '456' => 'zxc']], 'dfg', 'test' => ['ert' => '234'], 'cvf'];
print_r(func($asd));
/*
Array
(
[test[ert]] => 234
[asd[jkf][456]] => zxc
[asd[jkf][kjk]] => sdf
[asd[jkf][asd]] => 123
[asd[jkf][qwe]] => wer
[0] => dfg
[1] => cvf
)
*/
function flattenArray(array $notFlat) {
function _flattenArray(&$arrayRoot, $arrayCurr, $kS) {
foreach ($arrayCurr as $k => $v) {
if (is_array($v)) {
_flattenArray($arrayRoot, $v, $kS.'['.$k.']');
}
else {
$currentKey = (string) $kS.'['.$k.']';
$arrayRoot[$currentKey] = $v;
}
}
}
foreach ($notFlat as $k => $v) {
if (is_array($v)) {
_flattenArray($notFlat, $v, $k);
unset($notFlat[$k]);
}
}
return $notFlat;
}
Code ( https://3v4l.org/5LVii )
$asd = ['asd' => ['jkf' => ['qwe' => 'wer', 'asd' => '123', 'kjk' => 'sdf', '456' => 'zxc']], 'dfg', 'test' => ['ert' => '234'], 'cvf'];
function recurse($array,$key=''){
static $output=[];
foreach($array as $k=>$v){
if(is_array($v)){
recurse($v,$key?$key.'['.$k.']':$k);
}else{
$output[$key?$key.'['.$k.']':$k]=$v;
}
}
return $output;
}
var_export(recurse($asd));
Output:
array (
'asd[jkf][qwe]' => 'wer',
'asd[jkf][asd]' => '123',
'asd[jkf][kjk]' => 'sdf',
'asd[jkf][456]' => 'zxc',
0 => 'dfg',
'test[ert]' => '234',
1 => 'cvf',
)
There isn't much that I can explain. The snippet iterates and recurses the array, appending the keys as it recurses. static allows the reuse/build of $output.

Compare multidimensional array with simple array

I have two arrays I want to compare these two arrays and find the match. If 807 and 200 appears in same keys like 131 then create third array
array(131=>(807,200));
array1:-
Array([0] => 807,[1] => 200)
array2 :-
$mat= Array([0] => Array([131] => 807),[1] => Array([132] => 807),[2] => Array([125] => 200),[3] => Array([131] => 200))
My code:
<?php
$filtered = array();
array_walk_recursive($matchingskusarr, function($val, $key) use(&$filtered) {
if ($key === 131) {
echo "The key $key has the value $val<br>";
$filtered[$val] = $key;
}
});
echo "<pre>";
print_r($filtered);
echo "</pre>";
?>
You can use array_column like this:
$filtered = array_column($mat, 131);
//Output: Array ( [0] => 807 [1] => 200 )
Update 1:
$matchingskusarr = Array( 0 => Array(131 => 807), 1 => Array(132 => 807),2 => Array(125 => 200),3 => Array(131 => 200)) ;
$skus = array(0=>807, 1=>200);
function yourMatch($skus, $matchingskusarr) {
$continue = [];
foreach ($matchingskusarr as $array) {
//Get the first key !!!
foreach ($array as $key => $value);
//Column already tested just continue
if(isset($continue[$key])) {
continue;
}
//New column we need to check if it matches our $skus
$column = array_column($matchingskusarr, $key);
if($column == $skus) {
return [$key => $column ];
}
$continue[$key] = true;
}
return null;
}
print_r(yourMatch($skus, $matchingskusarr));
Demo: https://3v4l.org/Cr2L4

Search in a multidimensional assoc array

I have an array, looking like this:
[lund] => Array
(
[69] => foo
)
[berlin] => Array
(
[138] => foox2
)
[tokyo] => Array
(
[180] => foox2
[109] => Big entrance
[73] => foo
)
The thing is that there were duplicate keys, so I re-arranged them so I can search more specifically, I thought.
Previously I could just
$key = array_search('foo', $array);
to get the key but now I don't know how.
Question: I need key for value foo, from tokyo. How do I do that?
You can get all keys and value of foo by using this:
foreach ($array as $key => $value) {
$newArr[$key] = array_search('foo', $value);
}
print_r(array_filter($newArr));
Result is:
Array
(
[lund] => 69
[tokyo] => 109
)
If you don't mind about the hard code than you can use this:
array_search('foo', $array['tokyo']);
It just a simple example, you can modify it as per your requirement.
Try this
$a = array(
"land"=> array("69"=>"foo"),
"land1"=> array("138"=>"foo1"),
"land2"=> array('180' => 'foox2',
'109' => 'Big entrance',
'73' => 'foo'),
);
//print_r($a);
$reply = search_in_array($a, "foo");
print_r($reply);
function search_in_array($a, $search)
{
$result = array();
foreach($a as $key1 => $array ) {
foreach($array as $k => $value) {
if($value == "$search") {
array_push($result,"{$key1}=>{$k}");
breck;
}
}
}
return $result;
}
This function will return the key or null if the search value is not found.
function search($searchKey, $searchValue, $searchArr)
{
foreach ($searchArr as $key => $value) {
if ($key == $searchKey && in_array($searchValue, $value)) {
$results = array_search($searchValue, $value);
}
}
return isset($results) ? $results : null;
}
// var_dump(search('tokyo', 'foo', $array));
Since Question: I need key for value foo, from tokyo. How do i do that?
$key = array_search('foo', $array['tokyo']);
As a function:
function getKey($keyword, $city, $array) {
return array_search($keyword, $array[$city]);
}
// PS. Might be a good idea to wrap this array in an object and make getKey an object method.
If you want to get all cities (for example to loop through them):
$cities = array_keys($array);
I created solution using array iterator. Have a look on below solution:
$array = array(
'lund' => array
(
'69' => 'foo'
),
'berlin' => array
(
'138' => 'foox2'
),
'tokyo' => array
(
'180' => 'foox2',
'109' => 'Big entrance',
'73' => 'foo'
)
);
$main_key = 'tokyo'; //key of array
$search_value = 'foo'; //value which need to be search
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($iterator as $key => $value) {
$keys = array();
if ($value == $search_value) {
$keys[] = $key;
for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
$keys[] = $iterator->getSubIterator($i)->key();
}
$key_paths = array_reverse($keys);
if(in_array($main_key, $key_paths) !== false) {
echo "'{$key}' have '{$value}' value which traverse path is: " . implode(' -> ', $key_paths) . '<br>';
}
}
}
you can change value of $main_key and $serch_value according to your parameter. hope this will help you.
<?php
$lund = [
'69' => 'foo'
];
$berlin = [
'138' => 'foox2'
];
$tokyo = [
'180' => 'foox2',
'109' => 'Big entrance',
'73' => 'foo'
];
$array = [
$lund,
$berlin,
$tokyo
];
echo $array[2]['180']; // outputs 'foox2' from $tokyo array
?>
If you want to get key by specific key and value then your code should be:
function search_array($array, $key, $value)
{
if(is_array($array[$key])) {
return array_search($value, $array[$key]);
}
}
echo search_array($arr, 'tokyo', 'foo');
try this:
<?php
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 'On');
$array=array("lund" => array
(
69 => "foo"
),
"berlin" => array
(
138 => "foox2"
),
"tokyo" => array
(
180 => "foox2",
109 => "Big entrance",
73 => "foo"
));
function search($array, $arrkey1, $arrvalue2){
foreach($array as $arrkey=>$arrvalue){
if($arrkey == $arrkey1){
foreach($arrvalue as $arrkey=>$arrvalue){
if(preg_match("/$arrvalue/i",$arrvalue2))
return $arrkey;
}
}
}
}
$result=search($array, "tokyo", "foo"); //$array=array; tokyo="inside array to check"; foo="value" to check
echo $result;
You need to loop through array, since its 2 dimensional in this case. And then find corresponding value.
foreach($arr as $key1 => $key2 ) {
foreach($key2 as $k => $value) {
if($value == "foo") {
echo "{$k} => {$value}";
}
}
}
This example match key with $value, but you can do match with $k also, which in this case is $key2.

Combine repeating elements as array in a multidimensional array

I was wondering when working with multimedional arrays, if a certain key is the same, is there a way to combine the contents of other keys into its own array if a certain key is the same?
Something like this:
// name is the same in both arrays
array(
array(
'name' => 'Pepsi',
'store' => 'Over here',
'number' => '1234567'
),
array(
'name' => 'Pepsi',
'store' => 'Over here',
'number' => '5556734'
)
)
into something like this
array(
array(
'name' => 'Pepsi',
'store' => array('Over here', 'Over here'),
'number' => array('1234567', '5556734')
)
)
The defining key is checking if the name element is the same for the other arrays.
You can try a function like this.
function mergeByKey($array,$key){
$tmp_array = array();
foreach ( $array as $k => $row ) {
$merged = false;
foreach ($tmp_array as $k2 => $tmp_row){
if ($row[$key] == $tmp_row[$key]){
foreach ( $row as $k3 => $value ) {
if ($k3 == $key) continue;
$tmp_array[$k2][$k3][] = $value;
$merged = true;
}
}
if ($merged) break;
}
if (!$merged) {
$new_row = array();
foreach ( $row as $k4 => $value ) {
if ($k4 == $key) $new_row[$k4] = $value;
else $new_row[$k4] = array($value);
}
$tmp_array[] = $new_row;
}
}
foreach ( $tmp_array as $t => $row ) {
foreach ( $row as $t2 => $value ) {
if ( count($value) == 1 && $t2 != $key ) $tmp_array[$t][$t2] = $value[0];
}
}
return $tmp_array;
}
passing the array as first parameter and the key as second one.
I'm referencing to your array structure
edited: missed a piece
edited2: if resultin array contains elements with one string, it returns a string and not a array with one element
demo
This function uses a given field name as the grouping identifier and turns all other fields into arrays.
Note that single occurrences of your field name will yield arrays with a single element for the other fields. I wasn't sure whether that's a desirable trait, but just making sure you know ;-)
$arr = array(
array(
'name' => 'Pepsi',
'store' => 'Over here',
'number' => '1234567'
),
array(
'name' => 'Pepsi',
'store' => 'Over here',
'number' => '5556734'
)
);
function mergeArray($array, $column)
{
$res = array();
foreach ($array as $item) {
foreach ($item as $key => $value) {
if ($key === $column) {
$res[$column][$key] = $value;
} else {
$res[$column][$key][] = $value;
}
}
}
return array_values($res);
}
print_r(mergeArray($arr, 'name'));
Demo
Thanks to Gianni Lovece for her answer but I was able to develop a much simpler solution based on this problem. Just plug in the $result_arr to browse through and the $key you want to use as basis and it immediately outputs a multidimensional array with non-repeating values for repeating elements (see example below).
function multiarray_merge($result_arr, $key){
foreach($result_arr as $val){
$item = $val[$key];
foreach($val as $k=>$v){
$arr[$item][$k][] = $v;
}
}
// Combine unique entries into a single array
// and non-unique entries into a single element
foreach($arr as $key=>$val){
foreach($val as $k=>$v){
$field = array_unique($v);
if(count($field) == 1){
$field = array_values($field);
$field = $field[0];
$arr[$key][$k] = $field;
} else {
$arr[$key][$k] = $field;
}
}
}
return $arr;
}
For example, in the sample array for this question, running multiarray_merge($mysample, 'name') returns
array(
'Pepsi' => array(
'name' => 'Pepsi',
'store' => 'Over here', // String: Not an array since values are not unique
'number' => array('1234567', '5556734') // Array: Saved as array since values are unique
)
);

Get array's key recursively and create underscore separated string

Right now i got an array which has some sort of information and i need to create a table from it. e.g.
Student{
[Address]{
[StreetAddress] =>"Some Street"
[StreetName] => "Some Name"
}
[Marks1] => 100
[Marks2] => 50
}
Now I want to create database table like which contain the fields name as :
Student_Address_StreetAddress
Student_Address_StreetName
Student_Marks1
Student_Marks2
It should be recursive so from any depth of array it can create the string in my format.
You can use the RecursiveArrayIterator and the RecursiveIteratorIterator (to iterate over the array recursively) from the Standard PHP Library (SPL) to make this job relatively painless.
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
$keys = array();
foreach ($iterator as $key => $value) {
// Build long key name based on parent keys
for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
$key = $iterator->getSubIterator($i)->key() . '_' . $key;
}
$keys[] = $key;
}
var_export($keys);
The above example outputs something like:
array (
0 => 'Student_Address_StreetAddress',
1 => 'Student_Address_StreetName',
2 => 'Student_Marks1',
3 => 'Student_Marks2',
)
(Working on it, here is the array to save the trouble):
$arr = array
(
'Student' => array
(
'Address' => array
(
'StreetAddress' => 'Some Street',
'StreetName' => 'Some Name',
),
'Marks1' => '100',
'Marks2' => '50',
),
);
Here it is, using a modified version of #polygenelubricants code:
function dfs($array, $parent = null)
{
static $result = array();
if (is_array($array) * count($array) > 0)
{
foreach ($array as $key => $value)
{
dfs($value, $parent . '_' . $key);
}
}
else
{
$result[] = ltrim($parent, '_');
}
return $result;
}
echo '<pre>';
print_r(dfs($arr));
echo '</pre>';
Outputs:
Array
(
[0] => Student_Address_StreetAddress
[1] => Student_Address_StreetName
[2] => Student_Marks1
[3] => Student_Marks2
)
Something like this maybe?
$schema = array(
'Student' => array(
'Address' => array(
'StreetAddresss' => "Some Street",
'StreetName' => "Some Name",
),
'Marks1' => 100,
'Marks2' => 50,
),
);
$result = array();
function walk($value, $key, $memo = "") {
global $result;
if(is_array($value)) {
$memo .= $key . '_';
array_walk($value, 'walk', $memo);
} else {
$result[] = $memo . $key;
}
}
array_walk($schema, 'walk');
var_dump($result);
I know globals are bad, but can't think of anything better now.
Something like this works:
<?php
$arr = array (
'Student' => array (
'Address' => array (
'StreetAddress' => 'Some Street',
'StreetName' => 'Some Name',
),
'Marks1' => array(),
'Marks2' => '50',
),
);
$result = array();
function dfs($data, $prefix = "") {
global $result;
if (is_array($data) && !empty($data)) {
foreach ($data as $key => $value) {
dfs($value, "{$prefix}_{$key}");
}
} else {
$result[substr($prefix, 1)] = $data;
}
}
dfs($arr);
var_dump($result);
?>
This prints:
array(4) {
["Student_Address_StreetAddress"] => string(11) "Some Street"
["Student_Address_StreetName"] => string(9) "Some Name"
["Student_Marks1"] => array(0) {}
["Student_Marks2"] => string(2) "50"
}
function getValues($dataArray,$strKey="")
{
global $arrFinalValues;
if(is_array($dataArray))
{
$currentKey = $strKey;
foreach($dataArray as $key => $val)
{
if(is_array($val) && !empty($val))
{
getValues($val,$currentKey.$key."_");
}
else if(!empty($val))
{
if(!empty($strKey))
$strTmpKey = $strKey.$key;
else
$strTmpKey = $key;
$arrFinalValues[$strTmpKey]=$val;
}
}
}
}

Categories