Asked  7 Months ago    Answers:  5   Viewed   35 times

What is the best way to accomplish this?

 Answers

87

Use array_slice()

This is an example from the PHP manual: array_slice

$input = array("a", "b", "c", "d", "e");
$output = array_slice($input, 0, 3);   // returns "a", "b", and "c"

There is only a small issue

If the array indices are meaningful to you, remember that array_slice will reset and reorder the numeric array indices. You need the preserve_keys flag set to trueto avoid this. (4th parameter, available since 5.0.2).

Example:

$output = array_slice($input, 2, 3, true);

Output:

array([3]=>'c', [4]=>'d', [5]=>'e');
Wednesday, March 31, 2021
 
FyodorX
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
81

You can use array_slice or array_splice:

$b = array_slice($a, 0, 10);
$c = array_splice($a, 0, 10);

Note that array_slice copies the items of $a and returns them while array_splice does modify $a itself and only returns the items that have been removed from $a.

Saturday, May 29, 2021
 
IvanH
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
79

Here's a simpler way of going about it, I think. It depends on whether or not there are requirements that aren't explicitly stated.

A few things worth mentioning,

  1. You'd like to return the first 4 bytes that follow a '!', so you only need to buffer 4 chars
  2. I haven't got all the cables handy at the moment, so I've just banged-together something to run on the PC. In your case, instead of returning a copy of the string buffer you'd just output it with Serial.print

Code:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

class dummy
{
    public:
        dummy()
        {
            const char *testData = "234124!3455addg#5867";
            int dataLen = strlen(testData);
            mData = new char[dataLen+1];
            strcpy(mData, testData);
            mTotal = strlen(testData);
            mIndex = 0;
        }
        int available()
        {
            return mTotal - mIndex;
        }
        char read()
        {
            return mData[mIndex++];
        }
    private:
        char *mData;
        int mIndex;
        int mTotal;
};

char *testFunc()
{
    dummy *Serial = new dummy();
/// -------- 8< ------------ cut here until the next pair of scissors. put inside the loop function
/// your code does all of the functionality (reading and buffering) inside a single iteration of loop(). 
/// Normally, I'd expect a single character to be read each time. I'd expect loop() to be 
/// run 16 times before a result was output, since # is the 16th character of the string.
    char tmpBuffer[5] = {0};
    int bufferIndex = 0;
    bool marker1Seen = false;

    while (Serial->available() > 0)
    {
        char received = Serial->read();
        if (received == '!')
        {
            marker1Seen = true;
        }

        else if (received == '#')
        {
            return strdup(tmpBuffer);
        }

        else if (marker1Seen == true && bufferIndex < 4)
        {
            tmpBuffer[bufferIndex++] = received;
        }
    }
    // shouldn't get here if the input is well-formed
    return NULL;
/// -------- 8< ------------ cut here
}

int main()
{
    char *result = testFunc();
    cout << result;
    delete result;
}
Sunday, August 29, 2021
 
Deyson
answered 2 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 :