Asked  7 Months ago    Answers:  5   Viewed   29 times

I have an associative array and I need to find the numeric position of a key. I could loop through the array manually to find it, but is there a better way build into PHP?

$a = array(
  'blue'   => 'nice',
  'car'    => 'fast',
  'number' => 'none'
);

// echo (find numeric index of $a['car']); // output: 1

 Answers

60
echo array_search("car",array_keys($a));
Wednesday, March 31, 2021
 
eek
answered 7 Months ago
eek
84

You should use the key() function.

key($array)

should return the current key.

If you need the position of the current key:

array_search($key, array_keys($array));
Wednesday, March 31, 2021
 
Puneet
answered 7 Months ago
39

When you set cell values individually, you have the option of setting the datatype explicitly, but when you use the fromArray() method, you don't have this option.

However, by default, PHP uses a default value binder to identify datatypes from the values passed, and set the cell datatype accordingly. This default behaviour is defined in a class /PHPExcel/Cell/DefaultValueBinder.php.

So you can create your own value binder, as described in the PHPExcel Documentation, that would set every value as a string datatype.

Something like:

class PHPExcel_Cell_MyColumnValueBinder extends PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder
{
    protected $stringColumns = [];

    public function __construct(array $stringColumnList = []) {
        // Accept a list of columns that will always be set as strings
        $this->stringColumns = $stringColumnList;
    }

    public function bindValue(PHPExcel_Cell $cell, $value = null)
    {
        // If the cell is one of our columns to set as a string...
        if (in_array($cell->getColumn(), $this->stringColumns)) {
            // ... then we cast it to a string and explicitly set it as a string
            $cell->setValueExplicit((string) $value, PHPExcel_Cell_DataType::TYPE_STRING);
            return true;
        }
        // Otherwise, use the default behaviour
        return parent::bindValue($cell, $value);
    }
}

// Instantiate our custom binder, with a list of columns, and tell PHPExcel to use it
PHPExcel_Cell::setValueBinder(new PHPExcel_Cell_MyColumnValueBinder(['A', 'B', 'C', 'E', 'F']));

$objPHPExcel = new PHPExcel();
$objPHPExcel->getActiveSheet()->fromArray($dataArray,null,"A2");
Friday, May 28, 2021
 
Wilk
answered 5 Months ago
84

Just grabbing and unsetting the value is a much better approach (and likely faster too), but anyway, you can just count along

$result = array();
$idx = 0; // init offset
foreach ($input as $key => $value)
{
    if ($key == 'more')
    {
        // Remove the index "more" from $input and add it to $result.
        $result[] = key(array_splice($input, $idx, 1));
    }
    $idx++; // count offset
}
print_R($result);
print_R($input);

gives

Array
(
    [0] => more
)
Array
(
    [who] => me
    [what] => car
    [when] => today
)

BUT Technically speaking an associative key has no numerical index. If the input array was

$input = array
(
    'who' => 'me',
    'what' => 'car',
    'more' => 'car',
    'when' => 'today',
    'foo', 'bar', 'baz'
);

then index 2 is "baz". But since array_slice accepts an offset, which is not the same as a numeric key, it uses the element found at that position in the array (in order the elements appear), which is why counting along works.

On a sidenote, with numeric keys in the array, you'd get funny results, because you are testing for equality instead of identity. Make it $key === 'more' instead to prevent 'more' getting typecasted. Since associative keys are unique you could also return after 'more' was found, because checking subsequent keys is pointless. But really:

if(array_key_exists('more', $input)) unset($input['more']);
Saturday, May 29, 2021
 
nasty
answered 5 Months ago
13

There's a lot been written about PHPExcel and memory use, and I'm not going to repeat it all here.

Try reading some of the threads on the PHPExcel discussion board discussing the issue, such as this one; or previous answers here on SO such as this one or this one

Tuesday, July 6, 2021
 
Slinky
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :