in_array() is not working while calling php script in Yii2 - php

I have called core php function from controller of Yii2 in that in_array() function is not working but I have called individually then it is working.
following is my array which I have passed searchForId().
Array
(
[1] => Array
(
[2] => PRICE:
)
[4] => Array
(
[1] => S/NO
[3] => INSULATED TANK SIZE
[7] => QTY
[8] => U.PRICE(Qr.)
[10] => TOTAL PRICE (Qr.)
)
[5] => Array
(
[1] => 01
[3] => FZ 198(S) (11 x 6 x 3MH)
w/p (3+3)
[7] => 1 SET
[8] => 390,197.00
[10] => 390,197.00
)
[6] => Array
(
[1] => 02
[3] => FZ 36(S) (2 x 6 x 3MH)
w/p (3+3)
[7] => 1 SET
[8] => 121,232.00
[10] => 121,232.00
)
[7] => Array
(
[8] => Total in QAR
[10] => 511,429.00
)
)
this type of array I have got from excel sheet which I have read.
and my function is:
public function searchForId($array) {
foreach ($array as $key => $val) {
if (in_array('S/NO', $val)) {
return $key;
}
}
return null;
}
where I am doing wrong please help me.Thank You in advance!!

It seems to me you just need to do:
<?php
$array = [
"S/NO",
"INSULATED TANK SIZE",
"QTY",
"U.PRICE(Qr.)",
"TOTAL PRICE (Qr.)"
];
public function searchForId($array) {
$key = array_search('S/NO', $array);
return $key;
}
var_dump(searchForId($array));
Results here.
array_search() returns you the key already, or false if value is not found. Using in_array you won't directly get the key, if that's your aim. You could check if the return value is false|null at the place you call this function. I would do return $key ?? null(php 7+)
UPDATE
Here's how you can do with the last array you have given. Also see here.
public function searchForId($array) {
foreach($array as $k => $sub){
$key = array_search('S/NO', $sub);
if($key !== false){
return $key;
} else {
continue;
}
}
return null;
}
var_dump(searchForId($array));
Since the $key is int(0), and in all other cases you get bool(false) from array_search, you should check whether the $key is literally false and if so, continue to the next array :-)

Change your if statement as
if (in_array('S/NO', $val)) {
Well, the most reliable would to use array_search which would eliminate your whole function -
$key = array_search('S/NO', $array); //will return 1 for S/No and 7 for QTY.
Write array search inside your searchForId() function or try by trimming the values of array like shown above.

Related

select array value of an object in php

I'm just a beginner and would like to select a value of an array inside an object. I'm quite lost and don't know how to do.
ie : how to get de value of "thailande" inside this object ?
Forminator_Form_Entry_Model Object
(
[entry_id] => 42
[entry_type] => custom-forms
[form_id] => 24342
[is_spam] => 0
[date_created_sql] => 2020-07-02 11:42:21
[date_created] => 2 Juil 2020
[time_created] => 2 Juil 2020 # 11:42
[meta_data] => Array
(
[select-1] => Array
(
[id] => 87
[value] => thailande
)
[radio-1] => Array
(
[id] => 88
[value] => 1
)
[number-1] => Array
(
[id] => 89
[value] => 10
)
[_forminator_user_ip] => Array
(
[id] => 90
[value] => 84.101.156.169
)
)
[table_name:protected] => politis_5_frmt_form_entry
[table_meta_name:protected] => politis_5_frmt_form_entry_meta
)
thx a lot for your help.
It's fairly straightforward - you just go down the hierarchy one step at a time referencing the index you need.
So, assuming $obj in this example is an instance of Forminator_Form_Entry_Model then you would write
$obj->meta_data["select-1"]["value"]
which will point to the data you're looking for.
N.B. The ->index syntax is used to get properties of an object. the ["index"] syntax is used to get properties of an array.
You can try Callback Functions
function array_search_id($val_for_search, $array_data, $search_in_path='root') {
if(is_array($array_data) && count($array_data) > 0) { // if value has child
foreach($array_data as $key => $value) {
$paths_list = $search_in_path;
// Adding current key to search path
array_push($paths_list, $key);
if(is_array($value) && count($value) > 0) { // if value has child
$res = array_search_id($val_for_search, $value, $paths_list);//callback function
if ($res != null)
return $res;
}
else if($value == $val_for_search){
//if you wants path + result
return end($paths_list);
/*
//if you wants path
return join(" --> ", $paths_list);
*/
} //if value find in array return val
}
}
return null;
}
array_search_id('thailande', $your_array);

How to unset numeric index elements from a PHP array?

I have a collection of array it contains both numeric index as well as non numeric. I want to unset all the numeric indexes.
My array is something like this .
Array
(
[554] => Array
(
[0] => 554
[1] => Jiaqi Zheng
[2] => Female
[3] => 28
[4] => Table Tennis
[5] =>
[6] =>
[7] =>
[8] =>
[rank] => 554
[athlet_name] => Jiaqi Zheng
[gender] => Female
[sport] => Table Tennis
)
[555] => Array
(
[0] => 555
[1] => Zach Ziemek
[2] => Male
[3] => 23
[4] => Athletics
[5] =>
[6] =>
[7] =>
[8] =>
[rank] => 555
[athlet_name] => Zach Ziemek
[gender] => Male
[sport] => Athletics
)
)
Here i have to unset all the numeric index .
I used unset like this and its working fine for me .
unset(
$history_years_wise_country_wise_details_arr[ $history_years_wise_country_wise_details_info[0]][0],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][1],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][2],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][3],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][4],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][5],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][6],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][7],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][8]
);
Is there any way I will reduce the lines of codes? here 0 to 8 are in one series.
Can I unset all index in one line of code , as all are numeric?
Is it possible to use regular expression instead?
I want something like
unset(
$history_years_wise_country_wise_details_arr[ $history_years_wise_country_wise_details_info[0]][anything_which_will_take_index_from_0_to_8]);
Any suggestions?
Thank you
You could use array_filter() with is_string() function as its callback function:
$array = array_filter($array, 'is_string', ARRAY_FILTER_USE_KEY);
Use looping.
foreach ($array as $key => $value) {
if (is_numeric ($key)) {
unset($array [$key]);
}
}
Or use array_filter
$filtered = array_filter(
$array,
function ($key) {
return !is_numeric($key);
},
ARRAY_FILTER_USE_KEY
);
You shoud used foreach loop with is_numeric function like
foreach ($your_array as $key => $value) {
if (!is_numeric($key)) {
unset($arr[$key]);
}
}
i think there is no need of any regular expression
Since you have array inside array first you need to use array_map() and then traverse through array using array_filter(),
considering $array as your array:
$resultData = array_map([$this, 'allData'], $array);
public function allData($data)
{
$numericKeys = array_filter(array_keys($data), function ($k) {
return is_int($k);
});
// Updated Code
$arrayKeys = array_diff(array_keys($data),$numericKeys);
return array_intersect_key($data,array_flip($arrayKeys));
}

Merging by array value (and doing calculations with the other keys)

I'm having a difficult time finding a viable solution for this problem:
This is the array I have, and I want to group this array by product_name and count the quantity. But array structure needs to remain the same.
Array(
[0] => Array
(
[product_quantity] => 1
[product_name] => Appel
)
[1] => Array
(
[product_quantity] => 1
[product_name] => D-Day
)
[2] => Array
(
[product_quantity] => 4
[product_name] => D-Day
)
[3] => Array
(
[product_quantity] => 2
[product_name] => D-Day
)
[4] => Array
(
[product_quantity] => 1
[product_name] => Emiel
)
[5] => Array
(
[product_quantity] => 9
[product_name] => Emiel
)
[6] => Array
(
[product_quantity] => 3
[product_name] => Estella
)
[7] => Array
(
[product_quantity] => 4
[product_name] => Feeke
)
[8] => Array
(
[product_quantity] => 1
[product_name] => Feeke
)
[9] => Array
(
[product_quantity] => 7
[product_name] => Reset
)
[10] => Array
(
[product_quantity] => 1
[product_name] => Reset
))
What I need as output:
Array(
[0] => Array
(
[product_quantity] => 1
[product_name] => Appel
)
[1] => Array
(
[product_quantity] => 7
[product_name] => D-Day
)
[2] => Array
(
[product_quantity] => 10
[product_name] => Emiel
)
[3] => Array
(
[product_quantity] => 3
[product_name] => Estella
)
[4] => Array
(
[product_quantity] => 5
[product_name] => Feeke
)
[5] => Array
(
[product_quantity] => 8
[product_name] => Reset
)
)
I would love to hear some advice, or solutions on how to tackle this!
The goal can be reached in many ways. If you aim for speed then use a foreach to iterate over the input array, incrementally computing and storing the values into a new array (the body of the callback function below).
If you aim to impress your workmates or a recruiter with your knowledge of PHP then use array_reduce():
$output = array_values( // We don't need the keys of the generated array
array_reduce( // Incrementally process $input using a callback
$input,
// $carry is the partial result
// $item is the currently processed item
function(array $carry, array $item) {
// Extract the product name into a local variable
// we'll use it several times below
$name = $item['product_name'];
// If it's a new product then initialize its entry in the output
if (! array_key_exists($name, $carry)) {
$carry[$name] = array(
'product_quantity' => 0,
'product_name' => $name,
);
}
// Update the quantity of this group
$carry[$name]['product_quantity'] += $item['product_quantity'];
// Return the partial result
return $carry;
},
// Start with an empty array
array()
)
);
Update
The OP asked in a comment how to reuse the callback function and make it customizable ("how do I use a parameter to make 'product_name' dynamicaly?").
You can put the value ('product_name') into a variable ($key) outside the function and use the use language construct to let the anonymous function inherit it.
$key = 'product_name'; // The values needs to be in a variable
$output = array_values(
array_reduce(
$input,
// The 'use' keyword lets the anonymous function use a copy of $key
function(array $carry, array $item) use ($key) {
$name = $item[$key];
// The rest of the callback's code comes here unchanged
// ...
// Return the partial result
return $carry;
},
array()
)
);
See Example #3 on the documentation of anonymous functions for more examples.
You can store the callback function into a variable. This doesn't improve anything but the readability of the code. However, keep reading, this is just an intermediate step, the real magic happens below.
$key = 'abc';
$f = function(array $carry, array $item) use ($key) {
$name = $item[$key];
// The rest of the callback's code comes here unchanged
// ...
// Return the partial result
return $carry;
};
$output = array_values(array_reduce($input, $f, array()));
To make it really reusable you need to have a way to generate callbacks for different values of $key. Let's write a simple function that creates parametrized callbacks:
// This function creates a new callback that uses the value of argument $key
function makeFn($key)
{
return function(array $carry, array $item) use ($key) {
$name = $item[$key];
// The rest of the callback's code comes here unchanged
// ...
// Return the partial result
return $carry;
};
}
Now, let's use the new function. It creates different callback functions that can be used to reduce the array by using various keys:
$output1 = array_values(array_reduce($input, makeFn('product_name'), array()));
$output2 = array_values(array_reduce($input, makeFn('product_code'), array()));
I do not test it, but I think that it can solve your problem.
$stocks = [];
foreach ($products as $product) {
if (isset($stocks[$product['product_name']])) {
$stocks[$product['product_name']] += $product['product_quantity'];
} else {
$stocks[$product['product_name']] = $product['product_quantity'];
}
}
$finalList = [];
foreach ($stocks as $key => $stock) {
$finalList[] = [
'product_quantity' => $stock,
'product_name' => $key
];
}
print_r($finalList);

Minimum Match Logic

I have a very large data set that I'm trying to find the smallest set that will satisfy all the data sets. The final set must have one value in it that is in all of the data sets
A small sample of the data looks like
[0] => Array
(
[0] => 21
[1] => 21
[2] => 21
)
[1] => Array
(
[0] => 29
)
[2] => Array
(
[0] => 27
)
[3] => Array
(
[0] => 21
[1] => 21
[2] => 21
[3] => 39
[4] => 39
[5] => 43
)
[4] => Array
(
[0] => 29
[1] => 33
[2] => 33
[3] => 43
)
In this case I need logic to return 21, 27 and 29
The values returned needs to be be the minium number of values that match all arrays. Since I'm a PHP programmer, I writing this function in PHP.
You could follow this algorithm:
Updated after testing
$data=array(
array(21,29,27,57,22),
array(22,21,23,24,25,26),
array(31)
);
$map = array(); // keep a map of values and how many times they occur in other sets
foreach ($data as $setid => $set) {
foreach (array_unique($set) as $v) {
$map[$v][$setid] = true;
}
}
function reverseCount(array $a, array $b)
{
return count($b) - count($a);
}
// sort reversed on intersection count
uasort($map, 'reverseCount');
// after sorting the first number will be the one that occurs the most
// keep track of which sets have been hit
$setmap = array(); $n = count($data);
foreach ($map as $v => $sets) {
$hits = 0;
foreach ($sets as $setid => $dummy) {
if (!isset($setmap[$setid])) {
--$n;
++$hits;
$setmap[$setid] = true;
} else {
continue;
}
}
if ($hits) {
echo "value $v\n";
if (!$n) {
// all sets are hit
break;
}
}
}
Tested this time. It's not proven to always get the right result, because this is considered a greedy approximation algorithm.
But I hope it gives an idea of what you could do. Let me know if anything confuses you or if I'm dead wrong about it :)

Sort multidimensional array who has index

I got an array like that
Array
(
[0] => Array
(
[UnitESN] => 14296
[ScanNo] => 1
[ScanDate] => Nov 21
[ScanTime] => 10:15 AM
[Qualifiers] =>
[Notes] =>
[BadgeData] => Array
(
[0] => HEATH---
[1] => MCCU----
[2] => HER---
[3] => HCONNORS#------
[4] =>
[5] => 393
[6] => 13350
[7] =>
[8] =>
[9] => 111
)
[Signal] => +00/000
[ConnectionDelay] => 0407
)
[1] => Array
And so on... I want to order ASC or DESC... let's say on Col 8 and Col 8 is entry number 7 (8-1 because it start at zero) in BadgeData, any ideas ? I've try array_multisort but without succes.
Thanks
I'm glad you figured it out. Here's what I started writing before I got interrupted.
Basic uasort Example:
<?php
function cmp($a, $b) {
if ($a['BadgeData'][7] == $b['BadgeData'][7]) {
return 0;
}
// Ascending
return ($a['BadgeData'][7] < $b['BadgeData'][7]) ? -1 : 1;
}
// Order the values of the array based on the value in BadgeData[7] in ascending order..
uasort($array, 'cmp');
It looks like I may have misunderstood your original question though as I thought you wanted to sort the array by the value in BadgeData[7] but it seems like you wanted to sort the BadgeData for each array value.
Thanks to #Francois Deschenes to lead me on the right answer. Here's what I found :
http://ca2.php.net/manual/en/function.uasort.php#104714
I edited to fit my need. Thanks !
function SortArrayByCol(array $Array, $Key, $ASC=true, $Col=0) {
$Result = array();
$Values = array();
foreach($Array as $ID => $Value){
$Values[$ID] = isset($Value[$Key][$Col]) ? $Value[$Key][$Col] : null;
}
if($ASC){
asort($Values);
} else {
arsort($Values);
}
foreach($Values as $Key => $Value) {
$Result[$Key] = $Array[$Key];
}
return $Result;
}

Categories