Asked  7 Months ago    Answers:  5   Viewed   39 times

What exactly is the difference between array_map, array_walk and array_filter. What I could see from documentation is that you could pass a callback function to perform an action on the supplied array. But I don't seem to find any particular difference between them.

Do they perform the same thing?
Can they be used interchangeably?

I would appreciate your help with illustrative example if they are different at all.

 Answers

70
  • Changing Values:
    • array_map cannot change the values inside input array(s) while array_walk can; in particular, array_map never changes its arguments.
  • Array Keys Access:
    • array_map cannot operate with the array keys, array_walk can.
  • Return Value:
    • array_map returns a new array, array_walk only returns true. Hence, if you don't want to create an array as a result of traversing one array, you should use array_walk.
  • Iterating Multiple Arrays:
    • array_map also can receive an arbitrary number of arrays and it can iterate over them in parallel, while array_walk operates only on one.
  • Passing Arbitrary Data to Callback:
    • array_walk can receive an extra arbitrary parameter to pass to the callback. This mostly irrelevant since PHP 5.3 (when anonymous functions were introduced).
  • Length of Returned Array:
    • The resulting array of array_map has the same length as that of the largest input array; array_walk does not return an array but at the same time it cannot alter the number of elements of original array; array_filter picks only a subset of the elements of the array according to a filtering function. It does preserve the keys.

Example:

<pre>
<?php

$origarray1 = array(2.4, 2.6, 3.5);
$origarray2 = array(2.4, 2.6, 3.5);

print_r(array_map('floor', $origarray1)); // $origarray1 stays the same

// changes $origarray2
array_walk($origarray2, function (&$v, $k) { $v = floor($v); }); 
print_r($origarray2);

// this is a more proper use of array_walk
array_walk($origarray1, function ($v, $k) { echo "$k => $v", "n"; });

// array_map accepts several arrays
print_r(
    array_map(function ($a, $b) { return $a * $b; }, $origarray1, $origarray2)
);

// select only elements that are > 2.5
print_r(
    array_filter($origarray1, function ($a) { return $a > 2.5; })
);

?>
</pre>

Result:

Array
(
    [0] => 2
    [1] => 2
    [2] => 3
)
Array
(
    [0] => 2
    [1] => 2
    [2] => 3
)
0 => 2.4
1 => 2.6
2 => 3.5
Array
(
    [0] => 4.8
    [1] => 5.2
    [2] => 10.5
)
Array
(
    [1] => 2.6
    [2] => 3.5
)
Wednesday, March 31, 2021
 
cbcp
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
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
26

Starting from androidx source files, I've migrated custom classes based on old DialogPreference to new androidx.preference.DialogPreference with the following procedure:

Step 1

The old custom dialog class (e.g. CustomDialogPreference) based on legacy DialogPreference should be split into two separate classes:

  1. One class (e.g. CustomPreference) should extend androidx.preference.DialogPreference and will contain only the code related to preference handling (data management).
  2. Another class (e.g. CustomDialog) should extend androidx.preference.PreferenceDialogFragmentCompat and will contain only the code related to dialog handling (user interface), including onDialogClosed. This class should expose a static method newInstance to return an instance of this class.

Step 2

In the main fragment handling preferences based on PreferenceFragmentCompat the onDisplayPreferenceDialog method should be overridden to show the custom dialog, e.g.:

    private static final String DIALOG_FRAGMENT_TAG = "CustomPreference";

    @Override
    public void onDisplayPreferenceDialog(Preference preference) {
        if (getParentFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
            return;
        }

        if (preference instanceof CustomPreference) {
            final DialogFragment f = CustomDialog.newInstance(preference.getKey());
            f.setTargetFragment(this, 0);
            f.show(getParentFragmentManager(), DIALOG_FRAGMENT_TAG);
        } else {
            super.onDisplayPreferenceDialog(preference);
        }
    }
Monday, August 2, 2021
 
commonpike
answered 3 Months ago
19

The major difference between the two (other than add()'s String-only support) is that put() overwrites the previous presence of param with an existing key while add() does not.

For example:

params.put("etc", "etc");
params.put("key", "abc");
params.put("key", "xyz");

// Params: etc=etc&key=xyz

While add creates two params with the same key:

params.add("etc", "etc");
params.add("key", "abc");
params.add("key", "xyz");

// Params: etc=etc&key=abc&key=xyz

But what is the importance of doing this?

In the above example, the web-server would only read the last value of key i.e. xyz and not abc but this is useful when POSTing arrays:

params.add("key[]", "a");
params.add("key[]", "b");
params.add("key[]", "c");

// Params: key[]=a&key[]=b&key[]=c
// The server will read it as: "key" => ["a", "b", "c"]
Monday, August 23, 2021
 
jakubos
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 :