Asked  7 Months ago    Answers:  5   Viewed   46 times

I need to convert following data in csv to nested tree

S.No    Name
1       A
1.1     B
1.1.1   C
1.1.2   D
2       E
2.1     F
2.2     G

Is there any way S.No can be used to make array keys like 1.1.1 to $test[1][1][1] and then I can store corresponding Name as value.

or I should make parent child type array? What would be the best approach to convert this to tree/nested list?

 Answers

34

You can use this function to set a nested value within an array:

function set_nested_value(array &$array, $index, $value)
{
    $node = &$array;

    foreach (explode('.', $index) as $path) {
        $node = &$node[$path];
    }

    $node = $value;
}

$a = array();
set_nested_value($a, '1.1.1', 'A');
print_r($a);

Output:

Array
(
    [1] => Array
        (
            [1] => Array
                (
                    [1] => hello
                )

        )

)
Wednesday, March 31, 2021
 
CMOS
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
36

The following snippet should do the trick, adapted from some PHP Doctrine code I found on the web :

function toHierarchy($collection)
{
        // Trees mapped
        $trees = array();
        $l = 0;

        if (count($collection) > 0) {
                // Node Stack. Used to help building the hierarchy
                $stack = array();

                foreach ($collection as $node) {
                        $item = $node;
                        $item['children'] = array();

                        // Number of stack items
                        $l = count($stack);

                        // Check if we're dealing with different levels
                        while($l > 0 && $stack[$l - 1]['depth'] >= $item['depth']) {
                                array_pop($stack);
                                $l--;
                        }

                        // Stack is empty (we are inspecting the root)
                        if ($l == 0) {
                                // Assigning the root node
                                $i = count($trees);
                                $trees[$i] = $item;
                                $stack[] = & $trees[$i];
                        } else {
                                // Add node to parent
                                $i = count($stack[$l - 1]['children']);
                                $stack[$l - 1]['children'][$i] = $item;
                                $stack[] = & $stack[$l - 1]['children'][$i];
                        }
                }
        }

        return $trees;
}
Saturday, May 29, 2021
 
ajaybc
answered 5 Months ago
31

Arrays.asList can help here:

new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));
Sunday, June 27, 2021
 
Manju
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 :