Asked  7 Months ago    Answers:  5   Viewed   40 times

Normally, I'd be asking how to turn a 4-rowed, 3-columned array like this:

1      2        3
4      5        6
7      8        9
10    11       12

Into a 3-rowed, 4-columned array like: (I DON'T WANT THIS)

1   4   7   10
2   5   8   11
3   6   9   12

But actually, I want to turn it into this: (I WANT THIS)

1   5   9
2   6   10
3   7   11
4   8   12

In other words, I want to flip the rows and columns, but keep the same "width" and "height" of the new array. I've been stuck on this for over an hour.

This is the function I'm using to do a normal "flip" (the first example):

function flip($arr)
{
    $out = array();
    foreach ($arr as $key => $subarr)
    {
        foreach ($subarr as $subkey => $subvalue)
        {
            $out[$subkey][$key] = $subvalue;
        }
    }
    return $out;
}

 Answers

72

Just walk the array in the correct order. Assuming you have relatively small arrays, the easiest solution is just to create a brand new array during that walk.

A solution will be of the form:

$rows = count($arr);
$ridx = 0;
$cidx = 0;

$out = array();

foreach($arr as $rowidx => $row){
    foreach($row as $colidx => $val){
        $out[$ridx][$cidx] = $val;
        $ridx++;
        if($ridx >= $rows){
            $cidx++;
            $ridx = 0;
        }
    }
}
Wednesday, March 31, 2021
 
RompelStompel
answered 7 Months ago
42
function set_val(array &$arr, $path,$val)
{
   $loc = &$arr;
   foreach(explode('.', $path) as $step)
   {
     $loc = &$loc[$step];
   }
   return $loc = $val;
}
Wednesday, March 31, 2021
 
laurent
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
76

http://jsfiddle.net/CsgK9/2/

html:

<table>
    <tr>
        <td>1</td>
        <td>4</td>
        <td>7</td>
    </tr>
    <tr>
        <td>2</td>
        <td>5</td>
        <td>8</td>
    </tr>
    <tr>
        <td>3</td>
        <td>6</td>
        <td>9</td>
    </tr>
</table>


<p><a href="#">Do it.</a></p>

js:

$("a").click(function(){
    $("table").each(function() {
        var $this = $(this);
        var newrows = [];
        $this.find("tr").each(function(){
            var i = 0;
            $(this).find("td").each(function(){
                i++;
                if(newrows[i] === undefined) { newrows[i] = $("<tr></tr>"); }
                newrows[i].append($(this));
            });
        });
        $this.find("tr").remove();
        $.each(newrows, function(){
            $this.append(this);
        });
    });

    return false;
});
Tuesday, June 8, 2021
 
aaronhuisinga
answered 5 Months ago
51

You can use NumberFormatter.

You will still need to specify a certain amount of fraction digits, but you can just use a high enough value and be fine. It's not like the number of digits is really arbitrary. It's tied to your precision ini setting.

$formatter = new NumberFormatter("en_US", NumberFormatter::DECIMAL);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 42);
$formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, "'");
$formatter->setSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL, ",");
echo $formatter->format(123456.7891234); // 123'456,7891234

Demo https://3v4l.org/TCAIA

Wednesday, August 25, 2021
 
kwhohasamullet
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 :