How to search element in array with arrays - php

What is the best way to search element in this array?
$emailsArray= array(
'http://gmail.com' => 'gmail.com',
'http://poczta.onet.pl' => array('onet.pl','vp.pl', 'op.pl', 'spoko.pl', 'poczta.onet.pl', 'onet.eu', 'onet.com.pl', 'opoczta.pl','autograf.pl','vip.pl','vip.onet.pl'),
'http://poczta.wp.pl' => 'wp.pl',
'http://poczta.o2.pl' => 'o2.pl',
'http://mail.tlen.pl' => 'tlen.pl',
'http://poczta.interia.pl' => array('interia.pl','poczta.fm','interia.eu'),
'http://poczta.gazeta.pl' => 'gazeta.pl',
'http://pl.mail.yahoo.com' => array('yahoo.pl','yahoo.com'),
);

Depending on what you are searching for you could do something along these lines:
$emailDomain = 'o2.pl'; //grab this from an email you want to check
$emailsArray= array(
'http://gmail.com' => 'gmail.com',
'http://poczta.onet.pl' => array('onet.pl','vp.pl', 'op.pl', 'spoko.pl', 'poczta.onet.pl', 'onet.eu', 'onet.com.pl', 'opoczta.pl','autograf.pl','vip.pl','vip.onet.pl'),
'http://poczta.wp.pl' => 'wp.pl',
'http://poczta.o2.pl' => 'o2.pl',
'http://mail.tlen.pl' => 'tlen.pl',
'http://poczta.interia.pl' => array('interia.pl','poczta.fm','interia.eu'),
'http://poczta.gazeta.pl' => 'gazeta.pl',
'http://pl.mail.yahoo.com' => array('yahoo.pl','yahoo.com'),
);
foreach ($emailsArray as $host => $domains) {
if (is_string($domains)) {
$domains = array($domains);
}
if (in_array($emailDomain, $domains)) {
echo "The email is hosted at $host\n";
}
}

Do a foreach as $key => $value, within that an if is_array ($value) foreach $value as $key => $val
Then just check for matches within those loops

Related

PHP Foreach only get one data

i want to loop all the data i call but that runs only one data
I use Codeigniter framework
Model:
$this->db->where('group_user', 'upt_perpus')->order_by('idmodul', 'DESC')->get('menu')->result_array();
Controller:
$data = array(
'about' => array(
'sejarah' => 'Sejarah',
'visi_misi' => 'Visi, Misi & Tujuan',
'struktur' => 'Struktur Organisasi'
),
'services' => array(),
'peraturan' => array(
'umum' => 'Umum',
'khusus' => 'Khusus',
'pelayanan_perpus' => 'Pelayanan Perpustakaan'
)
);
$konten = $this->kontens->getPerpus();
foreach ($konten as $key) {
$data['services'] = array(
$key['slug'] => $key['judul']
);
}
return $data;
If you want an associative array in $data['services'], you need to assign to a key of the array.
foreach ($konten as $key) {
$data['services'][$key['slug']] = $key['judul'];
}

Modifying multidimensional array in PHP replacing keys as the values [duplicate]

This question already has answers here:
How to swap keys with values in array?
(6 answers)
Closed 6 years ago.
How would you modify the following code using only a foreach loop by replacing the keys as the values? For examples the salad, chicken, and pancakes keys would the values instead.
$meals = array(
'Lunch' => array(
'salad' => 'italian',
'salad2' => 'ranch',
'salad3' => 'sesame',
'salad4' => 'bluecheese'
),
'Dinner' => array(
'chicken' => 'grilled',
'chicken2' => 'baked',
'chicken3' => 'steamed',
'chicken4' => 'fried',
'chicken5' => 'broiled'
),
'Breakfast' => array(
'pancakes' => 'blueberry',
'pancakes2' => 'cherry',
'pancakes3' => 'strawberry',
'pancakes4' => 'lemon'
)
);
$newkey = array();
foreach($meals as $key => $value) {
unset($value);
// foreach ($)...
}
print_r($meals);
Edit
If you're unable to use array_flip(), then you'll need to do two loops: one for each meal, and one for each meal option.
Example:
foreach ($meals as $meal => $mealOptions)
{
$revisedMealOptions = array();
foreach ($mealOptions as $originalKey => $newKey)
{
$revisedMealOptions[$newKey] = $originalKey;
}
$meals[$meal] = $revisedMealOptions;
}
Original Answer
It's not entirely clear what you're after. If all you want is to turn:
'Lunch' => array(
'salad' => 'italian'
);
into
'Lunch' => array(
'italian' => 'salad'
);
use array_flip().
Example:
$meals['Lunch'] = array_flip($meals['Lunch']);
See http://php.net/manual/en/function.array-flip.php.
I'm sorry I am a total beginner. I need to use a nested $foreach loop to address this question. For class I'm not allowed to use the array_flip function. I have tried
$newkey = array();
foreach($meals as $key => $value) {
$newkey[] = $value;
foreach ($value as ){
}
}
So, it would read:
Basically I need it to read:
Array(
[Lunch] => array(
[italian] => salad,
[ranch] => salad2,
[sesame] => salad3,
[bluecheese] => salad4
)
)
The easiest way to do it would be like this:
$meals = array(
'Lunch' => array(
'salad' => 'italian',
'salad2' => 'ranch',
'salad3' => 'sesame',
'salad4' => 'bluecheese'
),
'Dinner' => array(
'chicken' => 'grilled',
'chicken2' => 'baked',
'chicken3' => 'steamed',
'chicken4' => 'fried',
'chicken5' => 'broiled'
),
'Breakfast' => array(
'pancakes' => 'blueberry',
'pancakes2' => 'cherry',
'pancakes3' => 'strawberry',
'pancakes4' => 'lemon'
)
);
$newArray = array();
foreach ($meals as $key => $value) {
$temp = array();
foreach ($value as $innerKey => $innerValue) {
$temp[$innerValue] = $innerKey;
}
$newArray[$key] = $temp;
}
unset($meals);
Basically, you create a new array and build it from the beginning with the use of the array $meals.

codeigniter 3 validation of associative array

I am trying to validate an associative array pushed from my JavaScript, using the validation library.
The following code is working except it is only validating (finding the values) for the last array within the associative array, is there a way for it to work for each instance of the array as it runs in the foreach?
code:
if (!empty($JSON)) {
foreach ($JSON AS $k => $data) {
foreach ($data AS $key => $value) {
$this->form_validation->set_data($data);
if($key == 'itemCode' . $k){
$this->form_validation->set_rules($key, 'Item Code', 'required');
}
if($key == 'Desc' . $k){
$this->form_validation->set_rules($key, 'Description', 'required');
}
if($key == 'Qty' . $k){
$this->form_validation->set_rules($key, 'Quantity', 'required|numeric');
}
if($key == 'Cost' . $k){
$this->form_validation->set_rules($key, 'Cost', 'required|numeric');
}
}
//$this->form_validation->reset_validation();
}
}
array output:
[0] => Array(
[Counter0] => 0
[itemCode0] => 1
[Desc0] => 1
[Qty0] => 1
[Cost0] => 1
[Total0] => 1
)
[1] => Array(
[Counter1] => 1
[itemCode1] => 2
[Desc1] => 2
[Qty1] => 2
[Cost1] => 2
[Total1] => 4
)
[2] => Array(
[Counter2] => 2
[itemCode2] => 3
[Desc2] => 3
[Qty2] => 3
[Cost2] => 3
[Total2] => 9
)
[3] => Array(
[Counter3] => 3
[itemCode3] => 4
[Desc3] => 4
[Qty3] => 4
[Cost3] => 4
[Total3] => 16
)
The problem is, the set_data function gets called between the set_rules function and according to CI
You have to call the set_data() method before defining any validation rules.
For more information take a look at the documentation
A possible method would be to catch all data and rules in an array
Below is an example how to achieve that, pls keep in mind i haven't tested it because i wrote it here down but you should be able to see the point
$arrValidationData = array();
$arrValidationRules = array();
$arrCatchValidationData = array(
"itemCode" => array(
"label" => "Item Code",
"rules" => "required"
),
"Desc" => array(
"label" => "Description",
"rules" => "required"
),
"Qty" => array(
"label" => "Quantity",
"rules" => "required|numeric"
),
"Cost" => array(
"label" => "Cost",
"rules" => "required|numeric"
),
);
if (!empty($JSON)) {
foreach ($JSON AS $k => $data) {
foreach ($data AS $key => $value) {
$keyToCatch = str_replace($k, "", $key);
if (isset($arrCatchValidationData[$keyToCatch]))
{
$arrValidationData[$key] = $value;
$arrValidationRules[] = array(
"field" => $key,
"label" => $arrCatchValidationData[$keyToCatch]['label'],
"required" => $arrCatchValidationData[$keyToCatch]['rules']
);
}
}
//$this->form_validation->reset_validation();
}
$this->form_validation->set_data($arrValidationData);
$this->form_validation->set_rules($arrValidationRules);
}
update: 30.05.2016
according to your comment you want to validate post and json data in the same call, in this case you simply have to merge the data
$arrValidationData = array_merge($arrValidationData, $_POST);

array sort by keys.

I have a following array,
$versions = array
(
'0.9.md5' => '/var/www/md5_test/0.9.md5',
'1.0.0.md5' => '/var/www/md5_test/1.0.0.md5',
'1.0.1.md5' => '/var/www/md5_test/1.0.1.md5',
'1.0.2.md5' => '/var/www/md5_test/1.0.2.md5',
'1.0.3.md5' => '/var/www/md5_test/1.0.3.md5',
'1.0.9.1.md5' => '/var/www/md5_test/1.0.9.1.md5',
'1.0.9.10.1.md5' => '/var/www/md5_test/1.0.9.10.1.md5',
'1.0.9.10.md5' => '/var/www/md5_test/1.0.9.10.md5',
'1.1.3.md5' => '/var/www/md5_test/1.1.3.md5',
'1.0.9.2.md5' => '/var/www/md5_test/1.0.9.2.md5',
'1.0.9.3.md5' => '/var/www/md5_test/1.0.9.3.md5',
'1.0.9.8.md5' => '/var/www/md5_test/1.0.9.8.md5',
'1.0.9.9.1.md5' => '/var/www/md5_test/1.0.9.9.1.md5',
'1.0.9.9.md5' => '/var/www/md5_test/1.0.9.9.md5',
'1.0.9.md5' => '/var/www/md5_test/1.0.9.md5',
'1.1.0.md5' => '/var/www/md5_test/1.1.0.md5',
'1.1.1.md5' => '/var/www/md5_test/1.1.1.md5',
'1.1.2.md5' => '/var/www/md5_test/1.1.2.md5',
);
In this array i want to sort this by keys. I have searched,
Ex: It should order like: 1.0.9.md5, 1.0.9.1.md5,.. , 1.0.9.10.md5, 1.0.9.10.1.md5
I have tried
ksort($versions);
But i could't get exactly what i want.
If these are version numbers, and you need to sort by the version so that 1.0.9.2.md5 comes before 1.0.9.10.1.md5 then you need a custom sort based on semantic versioning:
uksort($versions, 'version_compare');
Demo
Remove the ".md5" -> ksort() -> add the ".md5" again.
foreach($versions as $key => $value) {
$newKey = str_replace(".md5", "", $key);
$new[$newKey] = $value;
}
ksort($new);
foreach($new as $key => $value) {
$newKey = $key . ".md5";
$result[$newKey]= $value;
}
print_r($result);
Result:
Array
(
[0.9.md5] => /var/www/md5_test/0.9.md5
[1.0.0.md5] => /var/www/md5_test/1.0.0.md5
[1.0.1.md5] => /var/www/md5_test/1.0.1.md5
[1.0.2.md5] => /var/www/md5_test/1.0.2.md5
[1.0.3.md5] => /var/www/md5_test/1.0.3.md5
[1.0.9.md5] => /var/www/md5_test/1.0.9.md5
[1.0.9.1.md5] => /var/www/md5_test/1.0.9.1.md5
[1.0.9.10.md5] => /var/www/md5_test/1.0.9.10.md5
[1.0.9.10.1.md5] => /var/www/md5_test/1.0.9.10.1.md5
[1.0.9.2.md5] => /var/www/md5_test/1.0.9.2.md5
[1.0.9.3.md5] => /var/www/md5_test/1.0.9.3.md5
[1.0.9.8.md5] => /var/www/md5_test/1.0.9.8.md5
[1.0.9.9.md5] => /var/www/md5_test/1.0.9.9.md5
[1.0.9.9.1.md5] => /var/www/md5_test/1.0.9.9.1.md5
[1.1.0.md5] => /var/www/md5_test/1.1.0.md5
[1.1.1.md5] => /var/www/md5_test/1.1.1.md5
[1.1.2.md5] => /var/www/md5_test/1.1.2.md5
[1.1.3.md5] => /var/www/md5_test/1.1.3.md5
)

Convert non-nested and bracketed array to nested array

I'm in PHP and I've got an array that looks like this. A single dimension array whose keys are bracketed strings.
array(
'matrix[min_rows]' => '0',
'matrix[max_rows]' => '',
'matrix[col_order][]' => 'col_new_1',
'matrix[cols][col_new_0][type]' => 'text',
'matrix[cols][col_new_1][type]' => 'text',
'matrix[cols][col_new_0][label]' => 'Cell 1',
'matrix[cols][col_new_1][label]' => 'Cell 2',
'matrix[cols][col_new_0][name]' => 'cell_1',
'matrix[cols][col_new_1][name]' => 'cell_2',
'matrix[cols][col_new_0][instructions]' => '',
'matrix[cols][col_new_1][instructions]' => '',
'matrix[cols][col_new_0][width]' => '33%',
'matrix[cols][col_new_1][width]' => '',
'matrix[cols][col_new_0][settings][maxl]' => '',
'matrix[cols][col_new_0][settings][fmt]' => 'none',
'matrix[cols][col_new_0][settings][content]' => 'all',
'matrix[cols][col_new_1][settings][maxl]' => '140',
'matrix[cols][col_new_1][settings][multiline]' => 'y',
'matrix[cols][col_new_1][settings][fmt]' => 'none',
'matrix[cols][col_new_1][settings][content]' => 'all',
)
Is there any easy way to convert that to a normal nested array, ie:
array(
'matrix' => array(
'min_rows' => '0',
'max_rows' => '',
'col_order' => array('col_new_1'),
'cols' => array(
'col_new_0' => array(
'type' => 'text',
'label' => 'Cell 1',
....etc....
This is my current solution, but I was wondering if there's something more native or efficient:
foreach ($decoded_field_type_settings as $key => $value)
{
if (preg_match_all('/\[(.*?)\]/', $key, $matches))
{
$new_key = substr($key, 0, strpos($key, '['));
if ( ! isset($field_type_settings[$new_key]))
{
$field_type_settings[$new_key] = array();
}
$array =& $field_type_settings[$new_key];
$count = count($matches[1]) - 1;
foreach ($matches[1] as $i => $sub_key)
{
if ( ! $sub_key)
{
if ($i < $count)
{
$array[] = array();
}
else
{
$array[] = $value;
}
}
else
{
if ( ! isset($array[$sub_key]))
{
if ($i < $count)
{
$array[$sub_key] = array();
}
else
{
$array[$sub_key] = $value;
}
}
}
if ($i < $count)
{
$array =& $array[$sub_key];
}
}
}
else
{
$field_type_settings[$key] = $value;
}
}
UPDATE: I posted an answer below.
This might work, although it would probably generate some warnings:
$matrix = array();
foreach($arr as $key => $value) {
eval('$' . $key . ' = \'' . $value . '\';');
}
var_dump($matrix);
I think this should do it...
<?php
function convert2dTo3d($source) {
$refs = array();
$output = array();
foreach ($source AS $key => $val) {
$tok = strtok($key, '[]');
$prev_tok = NULL;
while ($tok !== FALSE) {
$this_ref =& $refs[$tok];
if ($prev_tok === NULL)
$output[$tok] =& $this_ref;
else
$refs[$prev_tok][$tok] =& $this_ref;
$prev_tok = $tok;
$tok = strtok('[]');
if ($tok === FALSE)
$refs[$prev_tok] = $val;
}
}
return $output;
}
// Test
$source = array(
'matrix[min_rows]' => '0',
'matrix[max_rows]' => '',
'matrix[col_order][]' => 'col_new_1',
'matrix[cols][col_new_0][type]' => 'text',
'matrix[cols][col_new_1][type]' => 'text',
'matrix[cols][col_new_0][label]' => 'Cell 1',
'matrix[cols][col_new_1][label]' => 'Cell 2',
'matrix[cols][col_new_0][name]' => 'cell_1',
'matrix[cols][col_new_1][name]' => 'cell_2',
'matrix[cols][col_new_0][instructions]' => '',
'matrix[cols][col_new_1][instructions]' => '',
'matrix[cols][col_new_0][width]' => '33%',
'matrix[cols][col_new_1][width]' => '',
'matrix[cols][col_new_0][settings][maxl]' => '',
'matrix[cols][col_new_0][settings][fmt]' => 'none',
'matrix[cols][col_new_0][settings][content]' => 'all',
'matrix[cols][col_new_1][settings][maxl]' => '140',
'matrix[cols][col_new_1][settings][multiline]' => 'y',
'matrix[cols][col_new_1][settings][fmt]' => 'none',
'matrix[cols][col_new_1][settings][content]' => 'all',
);
echo "<pre>";
print_r(convert2dTo3d($source));
echo "</pre>";
It seems that the OP wants, as output, an array declaration which can be parsed directly by PHP. So I suggest to use var_export().
$array = array(
'matrix[min_rows]' => '0',
// ......
// ......
// ......
'matrix[cols][col_new_1][settings][content]' => 'all'
);
$matrix = array();
foreach ($array as $key => $value)
{
// fix missing quotes around array indexes
$key = str_replace(array("[", "]", "['']"), array("['", "']", "[]"), $key);
// fill PHP array
eval('$'.$key.' = $value;');
}
var_export($matrix);
You can make use of a simple, regular expression based parser that creates a multidimensional array based on the information stored in the string per each key:
function parse_flat_matrix(array $flat)
{
$matrix = array();
$varname = 'matrix';
$nameToken = '[a-z0-9_]*';
foreach($flat as $key => $value)
{
$keys = preg_split(sprintf('/(\[%s\])/', $nameToken), $key, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
if ($varname !== array_shift($keys))
{
throw new InvalidArgumentException(sprintf('Invalid key %s.', $key));
}
$p =& $matrix;
foreach($keys as $k)
{
$r = preg_match(sprintf('/^\[(%s)\]$/', $nameToken), $k, $kk);
if (!$r)
{
throw new InvalidArgumentException(sprintf('Invalid subkey %s in key %s.', $k, $key));
}
if ('' === $kk[1])
{
$p =& $p[];
}
else
{
$p =& $p[$kk[1]];
}
}
$p = $value;
unset($p);
}
return $matrix;
}
With your example data given, it will create this array:
Array
(
[min_rows] => 0
[max_rows] =>
[col_order] => Array
(
[0] => col_new_1
)
[cols] => Array
(
[col_new_0] => Array
(
[type] => text
[label] => Cell 1
[name] => cell_1
[instructions] =>
[width] => 33%
[settings] => Array
(
[maxl] =>
[fmt] => none
[content] => all
)
)
[col_new_1] => Array
(
[type] => text
[label] => Cell 2
[name] => cell_2
[instructions] =>
[width] =>
[settings] => Array
(
[maxl] => 140
[multiline] => y
[fmt] => none
[content] => all
)
)
)
)
This was the simplest solution, involving no regex parsing:
$original_array = array(
'matrix[min_rows]' => '0',
'matrix[max_rows]' => '',
'matrix[col_order][]' => 'col_new_1',
'matrix[cols][col_new_0][type]' => 'text',
'matrix[cols][col_new_1][type]' => 'text',
'matrix[cols][col_new_0][label]' => 'Cell 1',
'matrix[cols][col_new_1][label]' => 'Cell 2',
'matrix[cols][col_new_0][name]' => 'cell_1',
'matrix[cols][col_new_1][name]' => 'cell_2',
'matrix[cols][col_new_0][instructions]' => '',
'matrix[cols][col_new_1][instructions]' => '',
'matrix[cols][col_new_0][width]' => '33%',
'matrix[cols][col_new_1][width]' => '',
'matrix[cols][col_new_0][settings][maxl]' => '',
'matrix[cols][col_new_0][settings][fmt]' => 'none',
'matrix[cols][col_new_0][settings][content]' => 'all',
'matrix[cols][col_new_1][settings][maxl]' => '140',
'matrix[cols][col_new_1][settings][multiline]' => 'y',
'matrix[cols][col_new_1][settings][fmt]' => 'none',
'matrix[cols][col_new_1][settings][content]' => 'all',
);
$query_string = http_build_query($original_array);
$final_array = array();
parse_str($query_string, $final_array);
var_dump($final_array);

Categories