I'm using PHPExcel, I have an multidimensional array called $sheetData. I want to be able to search the array for string D650.
For example if the string D650 is in $sheetData[12][E] I want it to return [12][E]. I can't seem to find a search function for PHPExcel. I've tried the code below but I am only getting one value back I need all the values. If the code isn't the best way to go about this please let me know. Thanks
function searchForId($id, $array) {
foreach ($array as $key => $val) {
$letter = "A";
for($i = 1; $i<= 26; $i++)
{
if ($val[$letter] === $id) {
return $key;
}
$letter++;
}
}
return null;
}
$id = searchForId('Denter code here650', $sheetData);
echo $id;
function searchForId($id, $array) {
foreach ($array as $row => $val) {
$letter = "A";
for($i = 1; $i<= 26; $i++) {
if ($val[$letter] === $id) {
return '[' . $row .'][' . $letter . ']';
}
$letter++;
}
}
return null;
}
though it might be more useful returning an array of row and column
function searchForId($id, $array) {
foreach ($array as $row => $val) {
$letter = "A";
for($i = 1; $i<= 26; $i++) {
if ($val[$letter] === $id) {
return array(
'row' => $row,
'column' => $letter
);
}
$letter++;
}
}
return null;
}
Related
i want to print the values of variables in an array but nothing appears, can someone help ?
<?php
$i = 0;
$array = array();
function addInArray($var, $array) {
$array[] = $var;
}
while ($i < 10) {
${"char" . $i} = 1;
addInArray(${"char" . $i}, $array);
foreach ($array as $values) {
echo $values.PHP_EOL;
}
$i++;
}
?>
Check Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?.
You either need to pass by reference &:
$i = 0;
$array = array();
function addInArray($var, &$array) { //HERE
$array[] = $var;
}
while ($i < 10) {
${"char" . $i} = 1;
addInArray(${"char" . $i}, $array);
foreach ($array as $values) {
echo $values.PHP_EOL;
}
$i++;
}
Or return the array from the function:
$i = 0;
$array = array();
function addInArray($var, $array) {
$array[] = $var;
return $array; //HERE
}
while ($i < 10) {
${"char" . $i} = 1;
$array = addInArray(${"char" . $i}, $array); ??HERE
foreach ($array as $values) {
echo $values.PHP_EOL;
}
$i++;
}
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"));
is there a simple way to access the nth element in a multidimensional array in php?
so for example
$arr = array(
[0] => array(1,4,7,3,53),
[6] => array(6,3,9,12,51,7),
[2] => array(9,94,54,3,87));
the 12th element would be 9.
array keys are not necessarily in order, nor each array row is of the same length.
Try this :
<?php
$arr = array(
'0'=> array(1,4,7,3,53),
'6'=>array(6,3,9,12,51,7),
'2'=>array(9,94,54,3,87)
);
$newArray=array();
foreach($arr as $array){
$newArray=array_merge($newArray, $array);
}
echo $newArray[11];
?>
untested, should work...
$arr = array(
0 => array(1,4,7,3,53), // your code was wrong here
6 => array(6,3,9,12,51,7),
2 => array(9,94,54,3,87));
function getnth ($array, $offset) {
$tmp_arr = array();
foreach ($array as $key => $value) {
foreach ($value as $val) {
$tmp_arr[] = $val;
}
}
return (isset($tmp_arr[$offset -1]) ? $tmp_arr[$offset -1] : FALSE);
}
getnth($arr, 12);
Edit: got to admit, the array_merge version is better....
Edit2: this is probably faster, if performance is an issue....
function getnth($array, $offset) {
$i = 0;
foreach ($array as $key => $value){
$size = count($value);
$i += $size;
if($offset <= $i) {
$new_off = $size - ($i - $offset) -1 ;
return $value[$new_off];
}
}
return FALSE;
}
function get_item($arr, $path, $delim = '.') {
$path = explode($delim, $path);
$result = $arr;
foreach ($path as $item) {
if (isset($result[$item])) {
$result = $result[$item];
} else {
return null;
}
}
return $result;
}
using:
echo get_item($arr, 'item.value.3.4.2.etc');
Hi i have a multidimensional associative array:
$array= array(
'Book1' => array('http://www.google.com', '45' ),
'Book2' => array('http://www.yahoo.com', '46', )
)
I need to be able to search $array on 'BookX' and then return the contents of 'BookX'.
Ive tried:
function array_searcher($needles, $array)
{
foreach ($needles as $needle) {
foreach ($array as $key )
{
if ($key == $needle)
{
echo $key;
}
}
}
}
with the search
$needles = array('Book1' , 'Book2' );
But this doesnt return anything
I might be misunderstanding, but this just sounds like the accessor. If not, could you clarify?
$array= array(
'Book1' => array('http://www.google.com', '45' ),
'Book2' => array('http://www.yahoo.com', '46', )
);
echo $array['Book1'];
EDIT: I did misunderstand your goal. I do have a comment on doing the two foreach loops. While this does work, when you have a very large haystack array, performance suffers. I would recommend using isset() for testing if a needle exists in the haystack array.
I modified the function to return an array of the found results to remove any performance hits from outputing to stdout. I ran the following performance test and while it might not do the same search over and over, it points out the inefficiency of doing two foreach loops when your array(s) are large:
function array_searcher($needles, $array) {
$result = array();
foreach ($needles as $needle) {
foreach ($array as $key => $value) {
if ($key == $needle) {
$result[$key] = $value;
}
}
}
return $result;
}
function array_searcher2($needles, $array) {
$result = array();
foreach ($needles as $needle) {
if (isset($array[$needle])) {
$result[$needle] = $array[$needle];
}
}
return $result;
}
// generate large haystack array
$array = array();
for($i = 1; $i < 10000; $i++){
$array['Book'.$i] = array('http://www.google.com', $i+20);
}
$needles = array('Book1', 'Book2');
$start = microtime(true);
for ($i = 0; $i < 1000; $i++) {
array_searcher($needles, $array);
}
echo (microtime(true) - $start)."\n";
// 14.2093660831
$start = microtime(true);
for ($i = 0; $i < 1000; $i++) {
array_searcher2($needles, $array);
}
echo (microtime(true) - $start)."\n";
// 0.00858187675476
If you want to search using the keys, you should access it as a key => value pair.
If you don't it only retrieves the value.
function array_searcher($needles, $array)
{
foreach ($needles as $needle)
{
foreach ($array as $key => $value)
{
if ($key == $needle)
{
echo $key;
}
}
}
}
I have a foreach loop and I want to see if there is a next element in the loop so I can compare the current element with the next. How can I do this? I've read about the current and next functions but I can't figure out how to use them.
A unique approach would be to reverse the array and then loop. This will work for non-numerically indexed arrays as well:
$items = array(
'one' => 'two',
'two' => 'two',
'three' => 'three'
);
$backwards = array_reverse($items);
$last_item = NULL;
foreach ($backwards as $current_item) {
if ($last_item === $current_item) {
// they match
}
$last_item = $current_item;
}
If you are still interested in using the current and next functions, you could do this:
$items = array('two', 'two', 'three');
$length = count($items);
for($i = 0; $i < $length - 1; ++$i) {
if (current($items) === next($items)) {
// they match
}
}
#2 is probably the best solution. Note, $i < $length - 1; will stop the loop after comparing the last two items in the array. I put this in the loop to be explicit with the example. You should probably just calculate $length = count($items) - 1;
You could probably use while loop instead of foreach:
while ($current = current($array) )
{
$next = next($array);
if (false !== $next && $next == $current)
{
//do something with $current
}
}
If the indexes are continuous:
foreach ($arr as $key => $val) {
if (isset($arr[$key+1])) {
echo $arr[$key+1]; // next element
} else {
// end of array reached
}
}
As php.net/foreach points out:
Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.
In other words - it's not a very good idea to do what you're asking to do. Perhaps it would be a good idea to talk with someone about why you're trying to do this, see if there's a better solution? Feel free to ask us in ##PHP on irc.freenode.net if you don't have any other resources available.
You could get the keys/values and index
<?php
$a = array(
'key1'=>'value1',
'key2'=>'value2',
'key3'=>'value3',
'key4'=>'value4',
'key5'=>'value5'
);
$keys = array_keys($a);
foreach(array_keys($keys) as $index ){
$current_key = current($keys); // or $current_key = $keys[$index];
$current_value = $a[$current_key]; // or $current_value = $a[$keys[$index]];
$next_key = next($keys);
$next_value = $a[$next_key] ?? null; // for php version >= 7.0
echo "{$index}: current = ({$current_key} => {$current_value}); next = ({$next_key} => {$next_value})\n";
}
result:
0: current = (key1 => value1); next = (key2 => value2)
1: current = (key2 => value2); next = (key3 => value3)
2: current = (key3 => value3); next = (key4 => value4)
3: current = (key4 => value4); next = (key5 => value5)
4: current = (key5 => value5); next = ( => )
if its numerically indexed:
foreach ($foo as $key=>$var){
if($var==$foo[$key+1]){
echo 'current and next var are the same';
}
}
The general solution could be a caching iterator. A properly implemented caching iterator works with any Iterator, and saves memory. PHP SPL has a CachingIterator, but it is very odd, and has very limited functionality. However, you can write your own lookahead iterator like this:
<?php
class NeighborIterator implements Iterator
{
protected $oInnerIterator;
protected $hasPrevious = false;
protected $previous = null;
protected $previousKey = null;
protected $hasCurrent = false;
protected $current = null;
protected $currentKey = null;
protected $hasNext = false;
protected $next = null;
protected $nextKey = null;
public function __construct(Iterator $oInnerIterator)
{
$this->oInnerIterator = $oInnerIterator;
}
public function current()
{
return $this->current;
}
public function key()
{
return $this->currentKey;
}
public function next()
{
if ($this->hasCurrent) {
$this->hasPrevious = true;
$this->previous = $this->current;
$this->previousKey = $this->currentKey;
$this->hasCurrent = $this->hasNext;
$this->current = $this->next;
$this->currentKey = $this->nextKey;
if ($this->hasNext) {
$this->oInnerIterator->next();
$this->hasNext = $this->oInnerIterator->valid();
if ($this->hasNext) {
$this->next = $this->oInnerIterator->current();
$this->nextKey = $this->oInnerIterator->key();
} else {
$this->next = null;
$this->nextKey = null;
}
}
}
}
public function rewind()
{
$this->hasPrevious = false;
$this->previous = null;
$this->previousKey = null;
$this->oInnerIterator->rewind();
$this->hasCurrent = $this->oInnerIterator->valid();
if ($this->hasCurrent) {
$this->current = $this->oInnerIterator->current();
$this->currentKey = $this->oInnerIterator->key();
$this->oInnerIterator->next();
$this->hasNext = $this->oInnerIterator->valid();
if ($this->hasNext) {
$this->next = $this->oInnerIterator->current();
$this->nextKey = $this->oInnerIterator->key();
} else {
$this->next = null;
$this->nextKey = null;
}
} else {
$this->current = null;
$this->currentKey = null;
$this->hasNext = false;
$this->next = null;
$this->nextKey = null;
}
}
public function valid()
{
return $this->hasCurrent;
}
public function hasNext()
{
return $this->hasNext;
}
public function getNext()
{
return $this->next;
}
public function getNextKey()
{
return $this->nextKey;
}
public function hasPrevious()
{
return $this->hasPrevious;
}
public function getPrevious()
{
return $this->previous;
}
public function getPreviousKey()
{
return $this->previousKey;
}
}
header("Content-type: text/plain; charset=utf-8");
$arr = [
"a" => "alma",
"b" => "banan",
"c" => "cseresznye",
"d" => "dio",
"e" => "eper",
];
$oNeighborIterator = new NeighborIterator(new ArrayIterator($arr));
foreach ($oNeighborIterator as $key => $value) {
// you can get previous and next values:
if (!$oNeighborIterator->hasPrevious()) {
echo "{FIRST}\n";
}
echo $oNeighborIterator->getPreviousKey() . " => " . $oNeighborIterator->getPrevious() . " -----> ";
echo "[ " . $key . " => " . $value . " ] -----> ";
echo $oNeighborIterator->getNextKey() . " => " . $oNeighborIterator->getNext() . "\n";
if (!$oNeighborIterator->hasNext()) {
echo "{LAST}\n";
}
}
You could get the keys of the array before the foreach, then use a counter to check the next element, something like:
//$arr is the array you wish to cycle through
$keys = array_keys($arr);
$num_keys = count($keys);
$i = 1;
foreach ($arr as $a)
{
if ($i < $num_keys && $arr[$keys[$i]] == $a)
{
// we have a match
}
$i++;
}
This will work for both simple arrays, such as array(1,2,3), and keyed arrays such as array('first'=>1, 'second'=>2, 'thrid'=>3).
A foreach loop in php will iterate over a copy of the original array, making next() and prev() functions useless. If you have an associative array and need to fetch the next item, you could iterate over the array keys instead:
foreach (array_keys($items) as $index => $key) {
// first, get current item
$item = $items[$key];
// now get next item in array
$next = $items[array_keys($items)[$index + 1]];
}
Since the resulting array of keys has a continuous index itself, you can use that instead to access the original array.
Be aware that $next will be null for the last iteration, since there is no next item after the last. Accessing non existent array keys will throw a php notice. To avoid that, either:
Check for the last iteration before assigning values to $next
Check if the key with index + 1 exists with array_key_exists()
Using method 2 the complete foreach could look like this:
foreach (array_keys($items) as $index => $key) {
// first, get current item
$item = $items[$key];
// now get next item in array
$next = null;
if (array_key_exists($index + 1, array_keys($items))) {
$next = $items[array_keys($items)[$index + 1]];
}
}
$next_data = $data;
$prev_key = null;
$prev_value = null;
foreach($data as $key => $value)
{
array_shift($next_data);
$next_key = key($next_data);
$next_value = $next_data[$next_key] ?? null;
// Do something here...
$prev_key = $key;
$prev_value = $value;
}
or if the array is associative then you could use current() similar to Andrei Krasutski's solution and key()
$values = [];
array_push($values, ["XYZ"=>100]);
array_push($values, ["ABC"=>10]);
array_push($values, ["XYZ"=>130]);
array_push($values, ["DEF"=>4]);
array_push($values, ["XYZ"=>5]);
$count = count($values);
foreach ($values as $index => $currentValue) {
if ($index < $count - 1) {
$nextValue = $values[$index + 1];
echo key($currentValue) . "=" . current($currentValue) . " followed by " . key($nextValue) . "/" . current($nextValue) . "<br>\n";
} else {
echo key($currentValue) . "=" . current($currentValue);
}
}
See https://onlinephp.io/c/dc58d for a running example.
or if the array is using named pairs:
$values = [];
array_push($values, ["type"=>"XYZ", "value"=>100]);
array_push($values, ["type"=>"ABC", "value"=>10]);
array_push($values, ["type"=>"XYZ", "value"=>130]);
array_push($values, ["type"=>"DEF", "value"=>"Lorem"]);
array_push($values, ["type"=>"XYZ", "value"=>5]);
$count = count($values);
foreach ($values as $index => $currentValue) {
if ($index < $count - 1) {
$nextValue = $values[$index + 1];
echo $currentValue['type'] . "=" . $currentValue['value']
. " followed by " . $nextValue['type'] . "/" . $nextValue['value'] . "<br>\n";
} else {
echo $currentValue['type'] . "=" . $currentValue['value'];
}
}