How to fill array in sequence? - php

I have the following iterration:
foreach ($filelines as $indexrow => $line) {
$columns = explode($splitter, $line);
$row = [];
foreach ($columns as $columnindex => $column) {
$column = $this->prepareValue($column);
if (RegexValidation::isNum($column)) {
$row[] = $this->setValue('num', $column, $indexrow, $columnindex);
} else {
if (RegexValidation::isMMYY($column)) {
$row[] = $this->setValue("mmyy", $column, $indexrow, $columnindex);
} else {
if (RegexValidation::isZip($column)) {
$row[] = $this->setValue("zip", $column, $indexrow, $columnindex);
}
}
}
}
$dataset[$indexrow] = $row;
}
I need to fill $row in a specific sequence, first is "zip," then "mmyy," then "num," etc. If there is no field, fill it as empty.
How to do this in the existing loop? Now I have a solution sort result array, but It needs to loop again.

I would use a special key and sort by the key. And - there is an elseif.
foreach ($filelines as $indexrow => $line) {
$columns = explode($splitter, $line);
$row = [];
foreach ($columns as $columnindex => $column) {
$column = $this->prepareValue($column);
$counter = 0;
if (RegexValidation::isNum($column)) {
$row['C_'.$counter++] = $this->setValue('num', $column, $indexrow, $columnindex);
} elseif (RegexValidation::isMMYY($column)) {
$row['B_'.$counter++] = $this->setValue("mmyy", $column, $indexrow, $columnindex);
} elseif (RegexValidation::isZip($column)) {
$row['A_'.$counter++] = $this->setValue("zip", $column, $indexrow, $columnindex);
} else { // If there is no field, fill it as empty
$row['Z_'.$counter++] = '';
}
}
ksort($row);
$dataset[$indexrow] = array_values($row);
}
Use A for the group you want to have first, then B for the group you want next, and so on. If you want to preserve the order within the group, you should have leading zeros on the counter, because A_10 ist sorted before A_9. Change that to A_09, or A_000009 depending on the size of your dataset.

Related

How to sort array by array of order?

I have the following function that accepts array and order:
function toCSV($data, $order)
{
$res = [];
foreach ($data as $index => $row) {
$str = [];
foreach ($row as $column) {
foreach ($order as $key) {
if ($column['key'] == $key)
$str[] = $column;
}
}
$res[$index] = $str;
}
return $res;
}
The $data is:
[[{"key":"num","value":"5132756002760855","indexrow":162,"columnindex":0}...]]
The $order is array of sequance:
$order = ['num', 'mm', 'yy', 'zip']
So, I try to sort first array by the second array. But it does not work for me. As result I get unsorted array.
Full $data array is:
[[{"key":"undetected","value":"","indexrow":25,"columnindex":0}],[{"key":"num","value":"5354562740628987","indexrow":64,"columnindex":0},{"key":"mmyy","value":"01\/26","indexrow":64,"columnindex":1}]]
The if in the most inner loop will be true at some point and then the element is added, so the order doesn't change. Assuming you have only keys that appear in order. If you switch the two most inner loops it will work but it is not very efficient. O(nm) instead of O(n+m).
function toCSV($data, $order) {
$res = [];
foreach ($data as $index => $row) {
$map = [];
$str = [];
foreach ($row as $column) {
if (array_key_exists($column['key'], $map))
$map[$column['key']][] = $column;
else
$map[$column['key']] = [$column];
}
foreach ($order as $key) {
if (array_key_exists($key, $map))
$str = array_merge($str, $map[$key]);
}
$res[$index] = $str;
}
return $res;
}
If a key can only exist once per row then you can simplify and don't have to use arrays in the map. Simplified version, also assuming each key in order appears once per column:
function toCSV($data, $order) {
$res = [];
foreach ($data as $index => $row) {
$map = [];
$str = [];
foreach ($row as $column)
$map[$column['key']] = $column;
foreach ($order as $key)
$str[] = $map[$key];
// to create key if it doesn't exist use the following:
// $str[] = array_key_exists($key, $map) ? $map[$key] : [];
$res[$index] = $str;
}
return $res;
}
Both versions will discard columns with keys not in $order.

Add capacity to Ford Fulkerson algorithm

I have a working php implementation of Ford Fulkerson algorithm, based on this great article http://www.geeksforgeeks.org/maximum-bipartite-matching/
At the moment, the matrix that control the algorithm can have in its cells a value of 1 or 0, to represent the possibility of every employee to work in that position. I would like to add capacity to the algorithm, basically place in the matrix higher values, like 2, 3 and so on to express the preference to choose an employee instead of another.
Do You have any suggestion on how to edit the algorithm to add capacity?
This is the algorithm code:
function maxMatch($matrix, $cols) {
$match = array();
foreach ($cols as $v => $item) {
$match[$item] = -1;
}
$result = 0;
foreach ($matrix as $u => $row) {
$seen = array();
foreach ($cols as $v => $item) {
$seen[$item] = 0;
}
if ($this->checkVertex($matrix, $u, $seen, $match)) {
print_r($match);
$result++;
}
}
return $match;
}
function checkVertex($matrix, $u, &$seen, &$match) {
foreach ($matrix[$u] as $v => $row) {
if ($matrix[$u][$v] && !$seen[$v]) {
$seen[$v] = TRUE;
if ($match[$v] < 0 || $this->checkVertex($matrix, $match[$v], $seen, $match)) {
$match[$v] = $u;
return TRUE;
}
}
}
return FALSE;
}
This is how I create the matrix:
function createMatrix($year, $month, $day, $shift) {
global $sql;
$result = $sql->query("VERY HUGE SELECT FOR EMPLOYEES AND POSITIONS MATCH");
while ($row = $result->fetch_assoc()) {
$matrix[$row['employee']][$row['position']] = 1;
}
return $matrix;
}
Thanks a lot,
Marco

Unable to print array outside foreach loop

$val = array();
foreach ($value as $key) {
$nested = $this->Mdl_mymodel->arr($key);
if($nested != NULL) {
$n = 0;
foreach ($nested as $nest) {
$n++;
$val[$n] = $nest->num;
}
}
else {
$val = '';
}
print_r($val);
}
print_r($val);
Here $val inside the loop is printed but outside it is empty. I think i am missing something. Please help!
Note: I am using codeigniter.
$val = array();
foreach ($value as $key) {
$nested = $this->Mdl_mymodel->arr();
if($nested != NULL) {
$n = 0;
foreach ($nested as $nest) {
$n++;
$val[$n] = $nest->num;
}
}
else {
// $val = ''; Commented this line because you have already
// initialized $val. If you do not get records,
// it will return as blank array.
}
print_r($val);
}
print_r($val);

Same position for duplicate values in a php array iterated with foreach loop

I have the following code that returns the indexed position of a value which its key matches the provided value in the parameter of the function($haystack).
$results = array("098"=>90,"099"=>89,"100"=>77,"101"=>77);
function getPosition($results,$StudentID){
arsort($results);
$index = 1;
$exists = '';
$keys = array_keys($results);
foreach($keys as $key)
{
if($key == $StudentID)
{
$score = $results[$key];
$position = $index;
}
$index++;
}
return $position;
}
echo getPosition($results,"098").'<br />';
echo getPosition($results,"099").'<br />';
echo getPosition($results,"100").'<br />';
echo getPosition($results,"101").'<br />';
The results are listed below:
90=1
89=2
77=4
77=3
Now my problem is:
1. I don't know how to get the function to return same position for two similar values(eg. 77);
edit: The StudentID parameter in the function is the key for array values.
eg. 098 is a key in the array and its the value for a particular StudentID
Simple return the positions as array.
$results = array("098"=>90,"099"=>89,"100"=>77,"101"=>77);
function getPosition($results,$StudentID)
{
arsort($results);
$index = 1;
$exists = '';
$keys = array_keys($results);
$position = array();
foreach($keys as $key)
{
if($key == $StudentID)
{
$score = $results[$key];
$position[] = $index;
}
$index++;
}
return $position;
}
print_r(getPosition($results,"77"));
Should you be searching for values rather than keys?
$results = array("098"=>90,"099"=>89,"100"=>77,"101"=>77);
function getPosition($results, $StudentID) {
$index = 1;
$indexes = array();
foreach ($results as $key=>$value) {
if ($value == $StudentID) $results[] = $index;
$index++;
}
return $indexes;
}
print_r(getPosition($results, "77"));

Multi-imensional Array based on Keys

Is there a simple way to take a single-dimensional array and convert it to a multi-dimensional array based on the spaces, or any character(s), in the keys?
$arr['foo1'] = 'bar1';
$arr['foo2'] = 'bar2';
$arr['foo3 tier1' ] = 'bar3';
$arr['foo4 tier1' ] = 'bar4';
and turn it into
$arr['foo1'] = 'bar1';
$arr['foo2'] = 'bar2';
$arr['foo3']['tier1'] = 'bar3';
$arr['foo4']['tier1'] = 'bar4';
you can always do some sort of foreach loop
$newarr = array();
foreach ($arr as $key => $value) {
$output = explode(' ',$key,2);
if(count($output)) {
$newarr[$output[0]][$output[1]] = $value;
} else {
$newarr[$key] = $value;
}
}
That code will only work for one space but you can expand it to multiple spaces, something like
function pivot($arr,$delimeter) {
$return = array();
foreach ($arr as $key => $value) {
$output = explode($delimeter,$key,2);
if(count($output)) {
if(strpos($output[1],$delimeter) > 0) {
$return[$output[0]] = pivot(array($output[1]=>$value),$delimeter);
} else {
$return[$output[0]][$output[1]] = $value;
}
} else {
$return[$key] = $value;
}
}
return $return;
}

Categories