Как изменить array

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

array_replaceЗаменяет элементы массива элементами других переданных массивов

Описание

array_replace(array $array, array ...$replacements): array

array_replace() не рекурсивная: значения первого массива
будут заменены вне зависимости от типа значений второго массива, даже если
это будут вложенные массивы.

Список параметров

array

Массив, элементы которого требуется заменить.

replacements

Массивы, из которых будут браться элементы для замены.
Значения следующего массива затирают значения предыдущего.

Возвращаемые значения

Возвращает массив (array).

Примеры

Пример #1 Пример использования array_replace()


<?php
$base
= array("orange", "banana", "apple", "raspberry");
$replacements = array(0 => "pineapple", 4 => "cherry");
$replacements2 = array(0 => "grape");$basket = array_replace($base, $replacements, $replacements2);
print_r($basket);
?>

Результат выполнения данного примера:

Array
(
    [0] => grape
    [1] => banana
    [2] => apple
    [3] => raspberry
    [4] => cherry
)

Смотрите также

  • array_replace_recursive() — Рекурсивно заменяет элементы первого массива элементами переданных массивов
  • array_merge() — Сливает один или большее количество массивов

steelpandrummer

10 years ago


<?php
// we wanted the output of only selected array_keys from a big array from a csv-table
// with different order of keys, with optional suppressing of empty or unused values
$values = array
(
   
'Article'=>'24497',
   
'Type'=>'LED',
   
'Socket'=>'E27',
   
'Dimmable'=>'',
   
'Wattage'=>'10W'
);$keys = array_fill_keys(array('Article','Wattage','Dimmable','Type','Foobar'), ''); // wanted array with empty value$allkeys = array_replace($keys, array_intersect_key($values, $keys));    // replace only the wanted keys$notempty = array_filter($allkeys, 'strlen'); // strlen used as the callback-function with 0==falseprint '<pre>';
print_r($allkeys);
print_r($notempty);/*
Array
(
    [Article] => 24497
    [Wattage] => 10W
    [Dimmable] =>
    [Type] => LED
    [Foobar] =>
)
Array
(
    [Article] => 24497
    [Wattage] => 10W
    [Type] => LED
)
*/
?>

marvin_elia at web dot de

8 years ago


Simple function to replace array keys. Note you have to manually select wether existing keys will be overrided.

/**
  * @param array $array
  * @param array $replacements
  * @param boolean $override
  * @return array
  */
function array_replace_keys(array $array, array $replacements, $override = false) {
    foreach ($replacements as $old => $new) {
        if(is_int($new) || is_string($new)){
            if(array_key_exists($old, $array)){
                if(array_key_exists($new, $array) && $override === false){
                    continue;
                }
                $array[$new] = $array[$old];
                unset($array[$old]);
            }
        }
    }
    return $array;
}


ali dot sweden19 at yahoo dot com

7 years ago


Here is a simple array_replace_keys function:

/**
     * This function replaces the keys of an associate array by those supplied in the keys array
     *
     * @param $array target associative array in which the keys are intended to be replaced
     * @param $keys associate array where search key => replace by key, for replacing respective keys
     * @return  array with replaced keys
     */
    private function array_replace_keys($array, $keys)
    {
        foreach ($keys as $search => $replace) {
            if ( isset($array[$search])) {
                $array[$replace] = $array[$search];
                unset($array[$search]);
            }
        }

        return $array;
    }

// Test Drive

print_r(array_replace_keys(['one'=>'apple', 'two'=>'orange'], ['one'=>'ett', 'two'=>'tvo']);
// Output
array(
'ett'=>'apple',
'tvo'=>'orange'
)


mail at romansklenar dot cz

13 years ago


To get exactly same result like in PHP 5.3, the foreach loop in your code should look like:

<?php

...

$count = func_num_args();

for (

$i = 1; $i < $count; $i++) {

   ...

}

...

?>



Check on this code:

<?php

$base
= array('id' => NULL, 'login' => NULL, 'credit' => NULL);

$arr1 = array('id' => 2, 'login' => NULL, 'credit' => 5);

$arr2 = array('id' => NULL, 'login' => 'john.doe', 'credit' => 100);

$result = array_replace($base, $arr1, $arr2);
/*

correct output:

array(3) {

   "id" => NULL

   "login" => string(8) "john.doe"

   "credit" => int(100)

}

your output:

array(3) {

   "id" => int(2)

   "login" => NULL

   "credit" => int(5)

}

*/

?>



Function array_replace "replaces elements from passed arrays into the first array" -- this means replace from top-right to first, then from top-right - 1 to first, etc, etc...


gmastro77 at gmail dot com

9 years ago


In some cases you might have a structured array from the database and one
of its nodes goes like this;

<?php
# a random node structure
$arr    = array(
   
'name'  => 'some name',
   
'key2'  => 'value2',
   
'title' => 'some title',
   
'key4'  => 4,
   
'json'  => '[1,0,1,1,0]'
);# capture these keys values into given order
$keys   = array( 'name', 'json', 'title' );
?>

Now consider that you want to capture $arr values from $keys.
Assuming that you have a limitation to display the content into given keys
order, i.e. use it with a vsprintf, you could use the following

<?php
# string to transform
$string = "<p>name: %s, json: %s, title: %s</p>";# flip keys once, we will use this twice
$keys   = array_flip( $keys );# get values from $arr
$test   = array_intersect_key( $arr, $keys );# still not good enough
echo vsprintf( $string, $test );
// output --> name: some name, json: some title, title: [1,0,1,1,0]

# usage of array_replace to get exact order and save the day

$test   = array_replace( $keys, $test );# exact output
echo vsprintf( $string, $test );
// output --> name: some name, json: [1,0,1,1,0], title: some title?>

I hope that this will save someone's time.


polecat at p0lecat dot com

12 years ago


I got hit with a noob mistake. :)

When the function was called more than once, it threw a function redeclare error of course.  The enviroment I was coding in never called it more than once but I caught it in testing and here is the fully working revision.  A simple logical step was all that was needed.

With PHP 5.3 still unstable for Debian Lenny at this time and not knowing if array_replace would work with multi-dimensional arrays, I wrote my own.  Since this site has helped me so much, I felt the need to return the favor. :)

<?php

       
// Polecat's Multi-dimensional array_replace function

        // Will take all data in second array and apply to first array leaving any non-corresponding values untouched and intact

       
function polecat_array_replace( array &$array1, array &$array2 ) {

           
// This sub function is the iterator that will loop back on itself ad infinitum till it runs out of array dimensions

           
if(!function_exists('tier_parse')){

                function
tier_parse(array &$t_array1, array&$t_array2) {

                    foreach (
$t_array2 as $k2 => $v2) {

                        if (
is_array($t_array2[$k2])) {

                           
tier_parse($t_array1[$k2], $t_array2[$k2]);

                        } else {

                           
$t_array1[$k2] = $t_array2[$k2];

                        }

                    }

                    return
$t_array1;

                }

            }

           
            foreach (

$array2 as $key => $val) {

                if (
is_array($array2[$key])) {

                   
tier_parse($array1[$key], $array2[$key]);

                } else {

                   
$array1[$key] = $array2[$key];

                }

            }

            return
$array1;

        }

?>



[I would also like to note] that if you want to add a single dimensional array to a multi, all you must do is pass the matching internal array key from the multi as the initial argument as such:

<?php

$array1
= array( "berries" => array( "strawberry" => array( "color" => "red", "food" => "desserts"), "dewberry" = array( "color" => "dark violet", "food" => "pies"), );
$array2 = array( "food" => "wine");
$array1["berries"]["dewberry"] = polecat_array_replace($array1["berries"]["dewberry"], $array2);

?>



This is will replace the value for "food" for "dewberry" with "wine".

The function will also do the reverse and add a multi to a single dimensional array or even a 2 tier array to a 5 tier as long as the heirarchy tree is identical.

I hope this helps atleast one person for all that I've gained from this site.


kyberprizrak

8 years ago


if(!function_exists('array_replace'))
{
  function array_replace()
  {
    $args = func_get_args();
    $num_args = func_num_args();
    $res = array();
    for($i=0; $i<$num_args; $i++)
    {
      if(is_array($args[$i]))
      {
        foreach($args[$i] as $key => $val)
        {
          $res[$key] = $val;
        }
      }
      else
      {
        trigger_error(__FUNCTION__ .'(): Argument #'.($i+1).' is not an array', E_USER_WARNING);
        return NULL;
      }
    }
    return $res;
  }
}

sun at drupal dot org

11 years ago


Instead of calling this function, it's often faster and simpler to do this instead:

<?php
$array_replaced
= $array2 + $array1;
?>

If you need references to stay intact:

<?php
$array2
+= $array1;
?>


lm713

8 years ago


If the arrays are associative (that is, their keys are strings), then I believe this function is identical to (the older) array_merge.

ricardophp yahoocombr

10 months ago


Concerning the affirmation:
If you want to append array elements from the second array to the first array while not overwriting the elements from the first array and not re-indexing, use the + array union operator

Clearing the fact (it means ...):
If the first array have a key and a value it will not be overlap by the new array. therefore if you have an array like [1=>"alpha", 2=>"beta"] and you got a new array telling [1=>"Alpha", 3=>"Gamma"] the final array will be [1=>"alpha", 2=>"beta", 3=>"Gamma"]. The values of first array will not be modified in the result array.

So, if you are building a concatenation array where the values sometimes overlaps each other keys and you must preserve values you better use array_merge instead "plus" sign


projacore at gmail dot com

7 years ago


You can also use:

<?php
$myarray
= [
"Orange",
"572" => "Banana",
"omg" => "Chili",
"nevermind" => "mango"
];$myarray[0] = "NO-Orange";
$myarray["572"] = "BANANAPHONE!!!";
$myarray["omg"] = "NO-Chili";print_r($myarray);?>

RESULT:
Array
(
    [0] => NO-Orange
    [572] => BANANAPHONE!!!
    [omg] => NO-Chili
    [nevermind] => mango
)

with regards


polecat at p0lecat dot com

12 years ago


I would like to add to my previous note about my polecat_array_replace function that if you want to add a single dimensional array to a multi, all you must do is pass the matching internal array key from the multi as the initial argument as such:

$array1 = array( "berries" => array( "strawberry" => array( "color" => "red", "food" => "desserts"), "dewberry" = array( "color" => "dark violet", "food" => "pies"), );

$array2 = array( "food" => "wine");

$array1["berries"]["dewberry"] = polecat_array_replace($array1["berries"]["dewberry"], $array2);

This is will replace the value for "food" for "dewberry" with "wine".

The function will also do the reverse and add a multi to a single dimensional array or even a 2 tier array to a 5 tier as long as the heirarchy tree is identical.

I hope this helps atleast one person for all that I've gained from this site.


Anonymous

7 years ago


The documentation is wrongly phrased: "array_replace() replaces the values of array1"  No replacing is done. A new array is created which looks like the one that would have resulted from the described replacement.

If you want to augment the set of indices in an array, use
       array_to_be_modified += array_with_indices_to_add;


tufan dot oezduman at googlemail dot com

13 years ago


a little enhancement to dyer85 at gmail dot com's function below:
<?php
if (!function_exists('array_replace'))
{
  function
array_replace( array &$array, array &$array1, $filterEmpty=false )
  {
   
$args = func_get_args();
   
$count = func_num_args()-1;

    for (

$i = 0; $i < $count; ++$i) {
      if (
is_array($args[$i])) {
        foreach (
$args[$i] as $key => $val) {
            if (
$filterEmpty && empty($val)) continue;
           
$array[$key] = $val;
        }
      }
      else {
       
trigger_error(
         
__FUNCTION__ . '(): Argument #' . ($i+1) . ' is not an array',
         
E_USER_WARNING
       
);
        return
NULL;
      }
    }

    return

$array;
  }
}
?>

this will allow you to "tetris-like" merge arrays:

<?php

$a

= array(
   
0 => "foo",
   
1 => "",
   
2 => "baz"
);
$b= array(
   
0 => "",
   
1 => "bar",
   
2 => ""
);print_r(array_replace($a,$b, true));?>
results in:
Array
(
    [0] => foo
    [1] => bar
    [2] => baz
)


ivijan dot stefan at gmail dot com

6 years ago


If you work on some realy old server below PHP5 you can use array_merge like "necessary evil" to replace values in array:

Here is example how you can use this:

<?php
if(function_exists("array_replace") && version_compare(phpversion(), '5.3.0', '>='))
       
$data = array_replace($array1, $array2); // (PHP 5 >= 5.3.0)
   
else
       
$data = array_merge($array1, $array2); // (PHP 5 < 5.3.0)
var_dump($data);
?>

This can also help someplugin developers to cover some old PHP versions.


array_replace

(PHP 5 >= 5.3.0, PHP 7)

array_replaceЗамена элементов массива элементами других переданных массивов

Описание

array array_replace
( array $array1
, array $array2
[, array $...
] )

array_replace() замещает значения массива
array1 значениями с такими же ключами из
других переданных массивов. Если ключ из первого массива присутствует
во втором массиве, его значение заменяется на значение из второго массива.
Если ключ есть во втором массиве, но отсутствует в первом — он будет создан
в первом массиве. Если ключ присутствует только в первом массиве, то
сохранится как есть. Если для замены передано несколько массивов, они
будут обработаны в порядке передачи и более поздние массивы будут
перезаписывать значения из предыдущих.

array_replace() не рекурсивная: значения первого массива
будут заменены вне зависимости от типа значений второго массива, даже если
это будут вложенные массивы.

Список параметров

array1

Массив, элементы которого требуется заменить.

array2

Массив, элементами которого будут заменяться элементы первого массива.

...

Еще массивы, из которых будут браться элементы для замены.
Значения следующего массива затирают значения предыдущего.

Возвращаемые значения

Возвращает массив (array) или NULL в случае ошибки.

Примеры

Пример #1 Пример использования array_replace()


<?php
$base 
= array("orange""banana""apple""raspberry");
$replacements = array(=> "pineapple"=> "cherry");
$replacements2 = array(=> "grape");$basket array_replace($base$replacements$replacements2);
print_r($basket);
?>

Результат выполнения данного примера:

Array
(
    [0] => grape
    [1] => banana
    [2] => apple
    [3] => raspberry
    [4] => cherry
)

Смотрите также

  • array_replace_recursive() — Рекурсивно заменяет элементы первого массива элементами переданных массивов
  • array_merge() — Сливает один или большее количество массивов

Вернуться к: Функции для работы с массивами

Представляем вам перевод статьи автора Thomas Lombart, которая была опубликована на сайте medium.freecodecamp.org. Перевод публикуется с разрешения автора.


Пример использования метода reduce для сокращения массива

Позвольте мне сделать смелое заявление: циклы часто бывают бесполезными и затрудняют чтение кода. Для итераций в массивах, поиска, сортировки элементов и других подобных действий вы можете использовать один из методов, приведенных ниже.

Несмотря на эффективность, большинство этих методов все еще малоизвестны и не очень популярны. Я проделаю для вас трудную работу и расскажу о самых полезных. Считайте эту статью своим путеводителем по методам массивов JavaScript.

Примечание: Прежде чем мы начнем, вам нужно узнать одну вещь: я с предубеждением отношусь к функциональному программированию. Чтобы избежать побочных эффектов, я стремлюсь применять методы, не изменяющие исходный массив напрямую. Я не говорю вам отказаться от изменения массива вообще, но стоит учитывать, что некоторые методы к этому приводят. В результате появляются побочные эффекты, нежелательные изменения и, как следствие, баги.

Изначально эта статья была опубликована на сайте thomlom.dev — там вы можете найти больше материалов по веб-разработке.

Основы

Есть четыре метода, о которых стоит знать, если вы работаете с массивами. Это map, filter, reduce и оператор spread. Они эффективны и полезны.

map
Вы будете часто пользоваться методом map. Вообще, каждый раз, когда вам нужно изменить элементы массива, рассматривайте этот вариант.

Он принимает один параметр — функцию, которая вызывается на каждом элементе массива, а затем возвращает новый массив так, что никаких побочных эффектов быть не может.

const numbers = [1, 2, 3, 4] 
const numbersPlusOne = numbers.map(n => n + 1) console.log(numbersPlusOne) // [2, 3, 4, 5]

Также вы можете создать новый массив, который хранит только одно определенное свойство объекта.

const allActivities = [
  { title: 'My activity', coordinates: [50.123, 3.291] }, 
  { title: 'Another activity', coordinates: [1.238, 4.292] }
] 
const allCoordinates = allActivities.map(activity => activity.coordinates) 
console.log(allCoordinates) // [[50.123, 3.291], [1.238, 4.292]]

Итак, запомните: когда вам нужно изменить массив, подумайте об использовании map.

filter
Название этого метода говорит само за себя: применяйте его, когда хотите отфильтровать массив.

Как и map, filter принимает в качестве единственного параметра функцию, которая вызывается на каждом элементе массива. Эта функция должна вернуть булево значение:

  • true — если вы хотите сохранить элемент в массиве;
  • false — если не хотите сохранять его.

В итоге у вас будет правильный новый массив с элементами, которые вы хотели оставить.

Например, в массиве можно сохранить только нечетные цифры.

const numbers = [1, 2, 3, 4, 5, 6] 
const oddNumbers = numbers.filter(n => n % 2 !== 0) console.log(oddNumbers) // [1, 3, 5]

Также можно использовать filter, чтобы убрать определенный элемент в массиве.

const participants = [
  { id: 'a3f47', username: 'john' }, 
  { id: 'fek28', username: 'mary' }, 
  { id: 'n3j44', username: 'sam' }, 
]
function removeParticipant(participants, id) { 
  return participants.filter(participant => participant.id !== id) 
} 
console.log(removeParticipant(participants, 'a3f47')) //  [{ id: 'fek28', username: 'mary' }, { id: 'n3j44', username: 'sam' }];

reduce
На мой взгляд, этот метод — самый сложный для понимания. Но как только вы его освоите, у вас появится куча возможностей.

Обычно метод reduce берет массив значений и соединяет их в одно значение. Он принимает два параметра, функцию callback (которая является редуктором) и опциональное начальное значение (которое является первым элементом массива по умолчанию). Сам редуктор принимает четыре параметра:

  • аккумулятор, собирающий возвращенные значения в редуктор;
  • текущее значение массива;
  • текущий индекс;
  • массив, для которого был вызван метод reduce.

В основном вы будете использовать только первые два параметра — аккумулятор и текущее значение.

Но давайте не будем сильно углубляться в теорию и рассмотрим самый распространенный пример применения reduce.

const numbers = [37, 12, 28, 4, 9] 
const total = numbers.reduce((total, n) => total + n) console.log(total) // 90

В первой итерации аккумулятор, являющийся суммой, принимает начальное значение 37. Возвращенное значение — 37 + n, где n = 12. Получаем 49.

Во время второй итерации аккумулятор равен 49, возвращенное значение — 49 + 28 = 77. И так далее.

Метод reduce настолько функциональный, что вы можете использовать его для построения множества методов массивов вроде map или filter.

const map = (arr, fn) => { 
  return arr.reduce((mappedArr, element) => { 
    return [...mappedArr, fn(element)] 
  }, []) 
} 
console.log(map([1, 2, 3, 4], n => n + 1)) // [2, 3, 4, 5]
const filter = (arr, fn) => { 
  return arr.reduce((filteredArr, element) => { 
    return fn(element) ? [...filteredArr] : [...filteredArr, element] 
  }, []) 
} 
console.log(filter([1, 2, 3, 4, 5, 6], n => n % 2 === 0)) // [1, 3, 5]

Как правило, мы присваиваем методу reduce начальное значение [] — аккумулятор. Для map мы запускаем функцию, результат которой добавляется в конец аккумулятора при помощи оператора spread (мы поговорим о нем ниже, не волнуйтесь). Для filter проделываем практически то же самое, только функцию filter запускаем на элементе. Если она принимает значение true, мы возвращаем предыдущий массив. В противном случае добавляем элемент в конец массива.

Давайте рассмотрим более сложный пример: сильно сократим массив [1, 2, 3, [4, [[[5, [6, 7]]]], 8]] до [1, 2, 3, 4, 5, 6, 7, 8].

function flatDeep(arr) { 
  return arr.reduce((flattenArray, element) => { 
    return Array.isArray(element) ? [...flattenArray, ...flatDeep(element)] : [...flattenArray, element] 
  }, []) 
} 
console.log(flatDeep([1, 2, 3, [4, [[[5, [6, 7]]]], 8]])) // [1, 2, 3, 4, 5, 6, 7, 8]

Этот пример очень похож на map, за исключением того, что здесь мы используем рекурсию. Я не буду подробно останавливаться на рекурсии, потому что это выходит за пределы нашей темы, но если вы хотите узнать больше, зайдите на этот отличный ресурс.

Оператор spread (ES2015)
Я согласен, это не метод. Однако оператор spread помогает достигать разных целей при работе с массивами. Вы можете применить его, чтобы расширить значения одного массива в другом, а затем сделать копию или связать несколько массивов вместе.

const numbers = [1, 2, 3] 
const numbersCopy = [...numbers]
console.log(numbersCopy) // [1, 2, 3]
const otherNumbers = [4, 5, 6]
const numbersConcatenated = [...numbers, ...otherNumbers]
console.log(numbersConcatenated) // [1, 2, 3, 4, 5, 6]

Внимание: оператор spread делает поверхностную копию оригинального массива. Но что значит «поверхностную»?

Такая копия будет дублировать оригинальные элементы как можно меньше. Если у вас есть массив с цифрами, строками или булевыми значениями (примитивные типы), проблем не возникает и значения действительно дублируются. Однако с объектами и массивами дело обстоит по-другому: копируется только ссылка на оригинальное значение. Поэтому если вы сделаете поверхностную копию массива, включающего объект, и измените объект в скопированном массиве, в оригинальном он тоже будет изменен, потому что у них одинаковая ссылка.

const arr = ['foo', 42, { name: 'Thomas' }]
let copy = [...arr]
copy[0] = 'bar'
console.log(arr) // No mutations: ["foo", 42, { name: "Thomas" }]
console.log(copy) // ["bar", 42, { name: "Thomas" }]
copy[2].name = 'Hello'
console.log(arr) // /! MUTATION ["foo", 42, { name: "Hello" }]
console.log(copy) // ["bar", 42, { name: "Hello" }]

Итак, если вы хотите создать реальную копию массива, который содержит объект или массивы, можете воспользоваться функцией lodash вроде cloneDeep. Но не нужно считать себя обязанным это сделать. Ваша цель — узнать, как все устроено под капотом.

Полезные методы

Ниже вы найдете другие методы, о которых тоже полезно знать и которые могут пригодиться для решения таких проблем, как поиск элемента в массиве, изъятие части массива и многое другое.

includes (ES2015)
Вы использовали когда-нибудь indexOf, чтобы узнать, есть элемент в массиве или нет? Ужасный способ проверки, правда?

К счастью, метод includes делает проверку за нас. Задайте параметр для includes, и он проведет поиск элемента по массиву.

const sports = ['football', 'archery', 'judo'] 
const hasFootball = sports.includes('football')
console.log(hasFootball) // true

concat
Метод concat можно применять для слияния двух или более массивов.

const numbers = [1, 2, 3]
const otherNumbers = [4, 5, 6]
const numbersConcatenated = numbers.concat(otherNumbers)
console.log(numbersConcatenated) // [1, 2, 3, 4, 5, 6]
// You can merge as many arrays as you want
function concatAll(arr, ...arrays) {
  return arr.concat(...arrays)
}
console.log(concatAll([1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12])) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

forEach
Если вы хотите выполнить действие для каждого элемента массива, можно использовать метод forEach. Он принимает функцию в качестве параметра, который, в свою очередь, тоже принимает три параметра: текущее значение, индекс и массив.

const numbers = [1, 2, 3, 4, 5] 
numbers.forEach(console.log)
// 1 0 [ 1, 2, 3 ]
// 2 1 [ 1, 2, 3 ]
// 3 2 [ 1, 2, 3 ]

indexOf
Этот метод используют, чтобы вернуть первый индекс, при котором элемент можно найти в массиве. Также с помощью indexOf часто проверяют наличие элемента в массиве. Честно говоря, сейчас я применяю его нечасто.

const sports = ['football', 'archery', 'judo'] 
const judoIndex = sports.indexOf('judo') 
console.log(judoIndex) // 2

find
Метод find похож на filter. Вам необходимо предоставить ему функцию, которая тестирует каждый элемент массива. Однако find прекращает тестировать элементы, как только находит тот, что прошел проверку. Это не filter, который выполняет итерации по всему массиву независимо от обстоятельств.

const users = [
  { id: 'af35', name: 'john' },
  { id: '6gbe', name: 'mary' },
  { id: '932j', name: 'gary' },
]
const user = users.find(user => user.id === '6gbe')
console.log(user) // { id: '6gbe', name: 'mary' }

Итак, используйте метод filter, когда хотите отфильтровать весь массив, а метод find, когда уверены, что ищете уникальный элемент в массиве.
findIndex
Этот метод практически такой же, как find, но он возвращает индекс первого найденного элемента вместо самого элемента.

const users = [
  { id: 'af35', name: 'john' },
  { id: '6gbe', name: 'mary' },
  { id: '932j', name: 'gary' },
]
const user = users.findIndex(user => user.id === '6gbe')
console.log(user) // 1

Вам может показаться, что findIndex и indexOf — это одно и тоже. Не совсем. Первым параметром indexOf является примитивное значение (булево значение, номер, строка, неопределенное значение или символ), тогда как первый параметр findIndex — функция обратного вызова.

Поэтому, когда вам нужно найти индекс элемента в массиве примитивных значений, вы можете работать с indexOf. Если у вас больше сложных элементов, например объектов, используйте findIndex.

slice
Когда вам нужно взять часть массива или скопировать массив, вы можете обратиться к методу slice. Но будьте внимательны: как и оператор spread, slice возвращает поверхностную копию.

const numbers = [1, 2, 3, 4, 5] 
const copy = numbers.slice()

В начале статьи я упомянул, что циклы часто бывают бесполезными. Давайте я покажу, как от них можно избавиться.

Предположим, вы хотите вернуть определенное количество сообщений чата из API и вам нужно, чтобы отображались только пять из них. Ниже приведены два подхода: один с циклами, другой с методом slice.

// The "traditional way" to do it:
// Determine the number of messages to take and use a for loop
const nbMessages = messages.length < 5 ? messages.length : 5
let messagesToShow = []
for (let i = 0; i < nbMessages; i++) {
  messagesToShow.push(posts[i])
}
// Even if "arr" has less than 5 elements,
// slice will return an entire shallow copy of the original array
const messagesToShow = messages.slice(0, 5)

some
Если вы хотите проверить, пройдет ли тест хотя бы один элемент массива, можно воспользоваться some. Как и map, filter или find, метод some принимает функцию обратного вызова в качестве единственного параметра, а затем возвращает значение true, если по крайней мере один элемент проходит проверку, и значение false, если нет.

Также some подходит для работы с разрешениями.

const users = [
  {
    id: 'fe34',
    permissions: ['read', 'write'],
  },
  {
    id: 'a198',
    permissions: [],
  },
  {
    id: '18aa',
    permissions: ['delete', 'read', 'write'],
  }
]
const hasDeletePermission = users.some(user => 
  user.permissions.includes('delete')
)
console.log(hasDeletePermission) // true

every
Этот метод похож на some, за исключением того, что он проверяет, чтобы условию соответствовал каждый элемент (а не один).

const users = [
  {
    id: 'fe34',
    permissions: ['read', 'write'],
  },
  {
    id: 'a198',
    permissions: [],
  },
  {
    id: '18aa',
    permissions: ['delete', 'read', 'write'],
  }
]
const hasAllReadPermission = users.every(user =>
  user.permissions.includes('read')
)
console.log(hasAllReadPermission) // false

flat (ES2019)
Это совершенно новые методы в мире JavaScript. Обычно flat создает новый массив, соединяя все элементы вложенного массива. Он принимает один параметр — число, которое указывает, насколько сильно вы хотите уменьшить размерность массива.

const numbers = [1, 2, [3, 4, [5, [6, 7]], [[[[8]]]]]]
const numbersflattenOnce = numbers.flat()
console.log(numbersflattenOnce) // [1, 2, 3, 4, Array[2], Array[1]]
const numbersflattenTwice = numbers.flat(2)
console.log(numbersflattenTwice) // [1, 2, 3, 4, 5, Array[2], Array[1]]
const numbersFlattenInfinity = numbers.flat(Infinity)
console.log(numbersFlattenInfinity) // [1, 2, 3, 4, 5, 6, 7, 8]

flatMap (ES2019)
Угадаете, что делает этот метод? Могу поспорить, вы поймете по одному его названию.

Сначала он запускает функцию mapping для каждого элемента, а затем сокращает массив за один раз. Проще простого!

const sentences = [
  'This is a sentence',
  'This is another sentence',
  "I can't find any original phrases",
]
const allWords = sentences.flatMap(sentence => sentence.split(' '))
console.log(allWords) // ["This", "is", "a", "sentence", "This", "is", "another", "sentence", "I", "can't", "find", "any", "original", "phrases"]

В этом примере у вас много предложений в массиве и вы хотите получить все слова. Вместо того чтобы использовать метод map и разделить все предложения на слова, а затем сократить массив, вы можете сразу использовать flatMap.

Затем вы можете подсчитать количество слов с функцией reduce (это не относится к flatMap, просто я хочу показать вам другой пример использования метода reduce).

const wordsCount = allWords.reduce((count, word) => {
  count[word] = count[word] ? count[word] + 1 : 1
  return count
}, {})
console.log(wordsCount) // { This: 2, is: 2, a: 1, sentence: 2, another: 1, I: 1, "can't": 1, find: 1, any: 1, original: 1, phrases: 1, }

Метод flatMap также часто используется в реактивном программировании. Пример вы можете посмотреть здесь.

join
Если вам нужно создать строку, основанную на элементах массива, метод join — то, что вам нужно. Он позволяет создавать новую строку, соединяя все элементы массива, разделенные предоставленным разделителем.

Например, с помощью join можно визуально отобразить всех участников деятельности.

const participants = ['john', 'mary', 'gary']
const participantsFormatted = participants.join(', ')
console.log(participantsFormatted) // john, mary, gary

А это более реальный пример, где вы можете сначала отфильтровать участников и получить их имена.

const potentialParticipants = [
  { id: 'k38i', name: 'john', age: 17 },
  { id: 'baf3', name: 'mary', age: 13 },
  { id: 'a111', name: 'gary', age: 24 },
  { id: 'fx34', name: 'emma', age: 34 },
]
const participantsFormatted = potentialParticipants
  .filter(user => user.age > 18)
  .map(user => user.name)
  .join(', ')
console.log(participantsFormatted) // gary, emma

from
Это статический метод, который создает новый массив из массивоподобного или итерируемого объекта, например строки. Он может пригодиться, когда вы работаете с объектной моделью документа.

const nodes = document.querySelectorAll('.todo-item') // this is an instance of NodeList
const todoItems = Array.from(nodes) // now, you can use map, filter, etc. as you're workin with an array!

Вы увидели, что мы использовали тип массива вместо экземпляра массива? Вот почему этот метод называется статическим.

Затем вы можете поразвлекаться с узлами, например зарегистрировать слушателей события на каждый из них при помощи метода forEach.

todoItems.forEach(item => {
  item.addEventListener('click', function() {
    alert(`You clicked on ${item.innerHTML}`)
  })
})

Методы, изменяющие массив, о которых стоит знать

Ниже приведены другие стандартные методы. Их отличие в том, что они изменяют оригинальный массив. В изменении нет ничего плохого, но стоит учитывать это при работе.

Если вы не хотите изменять оригинальный массив, работая с этими методами, сделайте его поверхностную или полную копию заранее.

const arr = [1, 2, 3, 4, 5] 
const copy = [...arr] // or arr.slice()

sort
Да, sort изменяет оригинальный массив. Фактически он сортирует элементы массива на месте. Метод сортировки по умолчанию трансформирует все элементы в строки и сортирует их в алфавитном порядке.

const names = ['john', 'mary', 'gary', 'anna']
names.sort()
console.log(names) // ['anna', 'gary', 'john', 'mary']

Будьте внимательны: если вы, например, перешли с языка Python, то метод sort при работе с массивом цифр не даст вам желаемого результата.

const numbers = [23, 12, 17, 187, 3, 90]
numbers.sort()
console.log(numbers) // [12, 17, 187, 23, 3, 90] 

Как же тогда отсортировать массив? Метод sort принимает одну функцию — функцию сравнения. Она принимает два параметра: первый элемент (а) и второй элемент для сравнения (b). Сравнение между этими двумя элементами требует возврата цифры:

  • если значение отрицательное — a сортируется перед b;
  • если значение положительное — b сортируется перед a;
  • если значение равно 0 — без изменений.

Затем можно отсортировать цифры.

const numbers = [23, 12, 17, 187, 3, 90]
numbers.sort((a, b) => a - b)
console.log(numbers) // [3, 12, 17, 23, 90, 187]

Или можно отсортировать даты от наиболее поздней.

const posts = [
  {
    title: 'Create a Discord bot under 15 minutes',
    date: new Date(2018, 11, 26),
  },
  {
    title: 'How to get better at writing CSS', 
    date: new Date(2018, 06, 17) },
  { 
    title: 'JavaScript arrays', 
    date: new Date() 
  },
]
posts.sort((a, b) => a.date - b.date) // Substracting two dates returns the difference in millisecond between them
console.log(posts)
// [ { title: 'How to get better at writing CSS',
//     date: 2018-07-17T00:00:00.000Z },
//   { title: 'Create a Discord bot under 15 minutes',
//     date: 2018-12-26T00:00:00.000Z },
//   { title: 'Learn Javascript arrays the functional way',
//     date: 2019-03-16T10:31:00.208Z } ]

fill
Метод fill изменяет или заполняет все элементы массива от начального индекса до конечного заданным значением. Пример отличного использования fill — заполнение нового массива начальными данными.

// Normally I would have called a function that generates ids and random names but let's not bother with that here.
function fakeUser() {
  return {
    id: 'fe38',
    name: 'thomas',
  }
}
const posts = Array(3).fill(fakeUser())
console.log(posts) // [{ id: "fe38", name: "thomas" }, { id: "fe38", name: "thomas" }, { id: "fe38", name: "thomas" }]

reverse
Мне кажется, название метода полностью объясняет его суть.

const numbers = [1, 2, 3, 4, 5]
numbers.reverse()
console.log(numbers) // [5, 4, 3, 2, 1]

pop
Этот метод убирает последний элемент из массива и возвращает его.

const messages = ['Hello', 'Hey', 'How are you?', "I'm fine"]
const lastMessage = messages.pop()
console.log(messages) // ['Hello', 'Hey', 'How are you?']
console.log(lastMessage) // I'm fine

Методы, которые можно заменить

В последнем разделе вы найдете методы, которые изменяют оригинальный массив и которым легко найти альтернативу. Я не утверждаю, что их нужно сбрасывать со счетов, просто хочу донести до вас, что у некоторых методов есть побочные эффекты и их можно заменить.

push
Этот метод используется часто. Он позволяет добавлять один или более элементов в массив, а также строить новый массив, основанный на предыдущем.

const todoItems = [1, 2, 3, 4, 5]
const itemsIncremented = []
for (let i = 0; i < items.length; i++) {
  itemsIncremented.push(items[i] + 1)
}
console.log(itemsIncremented) // [2, 3, 4, 5, 6]
const todos = ['Write an article', 'Proofreading']
todos.push('Publish the article')
console.log(todos) // ['Write an article', 'Proofreading', 'Publish the article']

Если вам нужно построить массив на основе другого, как в методе itemsIncremented, есть подходящие для этого и уже знакомые нам map, filter или reduce. Например, мы можем взять map, чтобы сделать это.

const itemsIncremented = todoItems.map(x => x + 1)

А если вы хотите использовать push, когда нужно добавить новый элемент, то пригодится оператор spread.

const todos = ['Write an article', 'Proofreading'] console.log([...todos, 'Publish the article'])

splice
К splice часто обращаются, чтобы убрать элемент на определенном индексе. Вы можете сделать то же самое с методом filter.

const months = ['January', 'February', 'March', 'April', ' May']
// With splice
months.splice(2, 1) // remove one element at index 2
console.log(months) // ['January', 'February', 'April', 'May']
// Without splice
const monthsFiltered = months.filter((month, i) => i !== 3)
console.log(monthsFiltered) // ['January', 'February', 'April', 'May']

Вы спросите: а если мне нужно убрать много элементов? Тогда используйте slice.


const months = ['January', 'February', 'March', 'April', ' May']
// With splice
months.splice(1, 3) // remove thirds element starting at index 1
console.log(months) // ['January', 'February', 'April', 'May']
// Without splice
const monthsFiltered = [...months.slice(0, 1), ...months.slice(4)]
console.log(monthsFiltered) // ['January', 'February', 'April', 'May']

shift
Метод shift убирает первый элемент массива и возвращает его. Чтобы сделать это в стиле функционального программирования, можно использовать оператор spread или rest.

const numbers = [1, 2, 3, 4, 5]
// With shift
const firstNumber = numbers.shift()
console.log(firstNumber) // 1
console.log(numbers) // [2, 3, 4, 5]
// Without shift
const [firstNumber, ...numbersWithoutOne] = numbers
console.log(firstNumber) // 1
console.log(numbersWithoutOne) // [2, 3, 4, 5]

unshift
Метод unshift позволяет добавлять один или более элементов в начало массива. Как и в shift, вы можете делать это с помощью оператора spread.

const numbers = [3, 4, 5]
// With unshift
numbers.unshift(1, 2)
console.log(numbers) // [1, 2, 3, 4, 5]
// Without unshift
const newNumbers = [1, 2, ...numbers]
console.log(newNumbers) // [1, 2, 3, 4, 5]

TL;DR

  • Когда вы хотите совершить какие-то операции с массивом, не используйте цикл for и не изобретайте велосипед, потому что, скорее всего, найдется метод из вышеперечисленных, который может сделать то, что вам нужно.
  • Чаще всего вы будете пользоваться методами map, filter, reduce и оператором spread — это важные инструменты для любого разработчика.
  • Существует также много методов массивов, которые хорошо бы знать: slice, some, flatMap, и т. д. Знакомьтесь с ними и применяйте при необходимости.
  • Побочные эффекты могут привести к нежелательным изменениям. Учитывайте, что некоторые методы изменяют ваш оригинальный массив.
  • Метод slice и оператор spread делают поверхностные копии. В результате объекты и подмассивы будут иметь одинаковые ссылки — это тоже стоит иметь в виду.
  • Старые методы, изменяющие массив, можно заменить новыми. Вы сами решаете, как поступать.

Теперь вы знаете все, что должны были знать о массивах JavaScript. Если вам понравилась эта статья, нажмите на кнопку «Похлопать» (до 50 раз, если захотите :-)) и поделитесь ей. И не стесняйтесь обмениваться впечатлениями в комментариях!

Is there a way to change all the numeric keys to «Name» without looping through the array (so a php function)?

[
    0 => 'blabla',
    1 => 'blabla',
    2 => 'blblll',
    // etc ...
]

Martijn's user avatar

Martijn

15.6k4 gold badges36 silver badges68 bronze badges

asked Nov 21, 2008 at 13:09

6

If you have an array of keys that you want to use then use array_combine

Given $keys = array(‘a’, ‘b’, ‘c’, …) and your array, $list, then do this:

$list = array_combine($keys, array_values($list));

List will now be array(‘a’ => ‘blabla 1’, …) etc.

You have to use array_values to extract just the values from the array and not the old, numeric, keys.

That’s nice and simple looking but array_values makes an entire copy of the array so you could have space issues. All we’re doing here is letting php do the looping for us, not eliminate the loop. I’d be tempted to do something more like:

foreach ($list as $k => $v) {
   unset ($list[$k]);

   $new_key =  *some logic here*

   $list[$new_key] = $v;
}

I don’t think it’s all that more efficient than the first code but it provides more control and won’t have issues with the length of the arrays.

answered Nov 21, 2008 at 13:41

Eric Goodwin's user avatar

Eric GoodwinEric Goodwin

2,9866 gold badges25 silver badges22 bronze badges

No, there is not, for starters, it is impossible to have an array with elements sharing the same key

$x =array(); 
$x['foo'] = 'bar' ; 
$x['foo'] = 'baz' ; #replaces 'bar'

Secondarily, if you wish to merely prefix the numbers so that

$x[0] --> $x['foo_0']  

That is computationally implausible to do without looping. No php functions presently exist for the task of «key-prefixing», and the closest thing is «extract» which will prefix numeric keys prior to making them variables.

The very simplest way is this:

function rekey( $input , $prefix ) { 
    $out = array(); 
    foreach( $input as $i => $v ) { 
        if ( is_numeric( $i ) ) { 
            $out[$prefix . $i] = $v; 
            continue; 
        }
        $out[$i] = $v;
    }
    return $out;
}

Additionally, upon reading XMLWriter usage, I believe you would be writing XML in a bad way.

<section> 
    <foo_0></foo_0>
   <foo_1></foo_1>
   <bar></bar>
   <foo_2></foo_2>
</section>

Is not good XML.

<section> 
   <foo></foo>
   <foo></foo>
   <bar></bar>
   <foo></foo>
</section>

Is better XML, because when intrepreted, the names being duplicate don’t matter because they’re all offset numerically like so:

section => { 
    0 => [ foo , {} ]
    1 => [ foo , {} ]
    2 => [ bar , {} ]
    3 => [ foo , {} ] 
}

Manoj Sharma's user avatar

Manoj Sharma

1,4672 gold badges13 silver badges20 bronze badges

answered Nov 21, 2008 at 13:21

Kent Fredric's user avatar

Kent FredricKent Fredric

56k14 gold badges107 silver badges149 bronze badges

1

This is an example prefixing all the keys with an underscore.

We use array_combine to combine the array keys with the array values, but we first run an array_map function on the array keys, which takes a simple function that adds the prefix.

$prefix = '_';
$arr = array_combine(
    array_map(function($v) use ($prefix){
       return $prefix.$v;
    }, array_keys($arr)),
    array_values($arr)
);

See a live example here https://3v4l.org/HABl7

delboy1978uk's user avatar

delboy1978uk

11.8k2 gold badges20 silver badges39 bronze badges

answered Dec 31, 2014 at 11:00

Aurelien's user avatar

AurelienAurelien

811 silver badge1 bronze badge

1

I added this for an answer to another question and seemed relevant. Hopefully might help someone that needs to change the value of the keys in an array. Uses built-in functions for php.

$inputArray = array('app_test' => 'test', 'app_two' => 'two');

/**
 * Used to remap keys of an array by removing the prefix passed in
 * 
 * Example:
 * $inputArray = array('app_test' => 'test', 'app_two' => 'two');
 * $keys = array_keys($inputArray);
 * array_walk($keys, 'removePrefix', 'app_');
 * $remappedArray = array_combine($keys, $inputArray);
 *
 * @param $value - key value to replace, should be from array_keys
 * @param $omit - unused, needed for prefix call
 * @param $prefix - prefix to string replace in keys
 */
function removePrefix(&$value, $omit, $prefix) {
    $value = str_replace($prefix, '', $value);
}

// first get all the keys to remap
$keys = array_keys($inputArray);

// perform internal iteration with prefix passed into walk function for dynamic replace of key
array_walk($keys, 'removePrefix', 'app_');

// combine the rewritten keys and overwrite the originals
$remappedArray = array_combine($keys, $inputArray);

// see full output of comparison
var_dump($inputArray);
var_dump($remappedArray);

Output:

array(2) {
  'attr_test' =>
  string(4) "test"
  'attr_two' =>
  string(3) "two"
}
array(2) {
  'test' =>
  string(4) "test"
  'two' =>
  string(3) "two"
}

answered Jun 22, 2015 at 22:17

akahunahi's user avatar

akahunahiakahunahi

1,73422 silver badges20 bronze badges

I think that he want:

$a = array(1=>'first_name', 2=>'last_name');
$a = array_flip($a);

$a['first_name'] = 3;
$a = array_flip($a);

print_r($a);

LPL's user avatar

LPL

16.7k6 gold badges48 silver badges95 bronze badges

answered Mar 31, 2010 at 0:47

intel's user avatar

intelintel

291 bronze badge

1

The solution to when you’re using XMLWriter (native to PHP 5.2.x<) is using $xml->startElement('itemName'); this will replace the arrays key.

Mouna Cheikhna's user avatar

answered Nov 21, 2008 at 13:30

change array key name «group» to «children».

<?php
echo json_encode($data);

function array_change_key_name( $orig, $new, &$array ) {
    foreach ( $array as $k => $v ) {
        $res[ $k === $orig ? $new : $k ] = ( (is_array($v)||is_object($v)) ? array_change_key_name( $orig, $new, $v ) : $v );
    }
    return $res;
}

echo '<br>=====change "group" to "children"=====<br>';
$new = array_change_key_name("group" ,"children" , $data);
echo json_encode($new);
?>

result:

{"benchmark":[{"idText":"USGCB-Windows-7","title":"USGCB: Guidance for Securing Microsoft Windows 7 Systems for IT Professional","profile":[{"idText":"united_states_government_configuration_baseline_version_1.2.0.0","title":"United States Government Configuration Baseline 1.2.0.0","group":[{"idText":"security_components_overview","title":"Windows 7 Security Components Overview","group":[{"idText":"new_features","title":"New Features in Windows 7"}]},{"idText":"usgcb_security_settings","title":"USGCB Security Settings","group":[{"idText":"account_policies_group","title":"Account Policies group"}]}]}]}]}

=====change "group" to "children"=====

{"benchmark":[{"idText":"USGCB-Windows-7","title":"USGCB: Guidance for Securing Microsoft Windows 7 Systems for IT Professional","profile":[{"idText":"united_states_government_configuration_baseline_version_1.2.0.0","title":"United States Government Configuration Baseline 1.2.0.0","children":[{"idText":"security_components_overview","title":"Windows 7 Security Components Overview","children":[{"idText":"new_features","title":"New Features in Windows 7"}]},{"idText":"usgcb_security_settings","title":"USGCB Security Settings","children":[{"idText":"account_policies_group","title":"Account Policies group"}]}]}]}]}

Manoj Sharma's user avatar

Manoj Sharma

1,4672 gold badges13 silver badges20 bronze badges

answered Jan 9, 2013 at 3:00

dingyuchi's user avatar

dingyuchidingyuchi

2262 silver badges4 bronze badges

Use array array_flip in php

$array = array ( [1] => Sell [2] => Buy [3] => Rent [4] => Jobs )
print_r(array_flip($array));
Array ( [Sell] => 1 [Buy] => 2 [Rent] => 3 [Jobs] => 4 ) 

Jérôme Verstrynge's user avatar

answered Oct 29, 2009 at 9:29

I did this for an array of objects. Its basically creating new keys in the same array and unsetting the old keys.

public function transform($key, $results)
{
    foreach($results as $k=>$result)
    {
        if( property_exists($result, $key) )
        { 
            $results[$result->$key] = $result;
            unset($results[$k]);
        }
    }

    return $results;
}

answered May 3, 2012 at 22:28

Darren Cato's user avatar

Darren CatoDarren Cato

1,37416 silver badges22 bronze badges

<?php
    $array[$new_key] = $array[$old_key];
    unset($array[$old_key]);
?>

answered Jun 12, 2015 at 14:20

Red Web's user avatar

To have the same key I think they must be in separate nested arrays.

for ($i = 0; $i < count($array); $i++) {
    $newArray[] = ['name' => $array[$i]];
};

Output:

0 => array:1 ["name" => "blabla"]
1 => array:1 ["name" => "blabla"]
2 => array:1 ["name" => "blblll"]

answered Jun 6, 2017 at 3:53

Jeffrey's user avatar

JeffreyJeffrey

1,9381 gold badge25 silver badges22 bronze badges

You could create a new array containing that array, so:

<?php
$array = array();
$array['name'] = $oldArray;
?>

answered Nov 21, 2008 at 13:33

Sebastian Hoitz's user avatar

Sebastian HoitzSebastian Hoitz

9,31513 gold badges61 silver badges76 bronze badges

I was looking for some standard PHP function to replace some value of an array with other, but surprisingly I haven’t found any, so I have to write my own:

function array_replace_value(&$ar, $value, $replacement)
{
    if (($key = array_search($ar, $value)) !== FALSE) {
        $ar[$key] = $replacement;
    }
}

But I still wonder — for such an easy thing there must already be some function for it! Or maybe much easier solution than this one invented by me?

Note that this function will only do one replacement. I’m looking for existing solutions that similarly replace a single occurrence, as well as those that replace all occurrences.

outis's user avatar

outis

74.4k21 gold badges149 silver badges219 bronze badges

asked Dec 29, 2011 at 14:05

Tomas's user avatar

12

Instead of a function that only replaces occurrences of one value in an array, there’s the more general array_map:

array_map(function ($v) use ($value, $replacement) {
    return $v == $value ? $replacement : $v;
}, $arr);

To replace multiple occurrences of multiple values using array of value => replacement:

array_map(function ($v) use ($replacement) {
    return isset($replacement[$v]) ? $replacement[$v] : $v;
}, $arr);

To replace a single occurrence of one value, you’d use array_search as you do. Because the implementation is so short, there isn’t much reason for the PHP developers to create a standard function to perform the task. Not to say that it doesn’t make sense for you to create such a function, if you find yourself needing it often.

answered Dec 29, 2011 at 14:19

outis's user avatar

outisoutis

74.4k21 gold badges149 silver badges219 bronze badges

5

While there isn’t one function equivalent to the sample code, you can use array_keys (with the optional search value parameter), array_fill and array_replace to achieve the same thing:

EDIT by Tomas: the code was not working, corrected it:

$ar = array_replace($ar,
    array_fill_keys(
        array_keys($ar, $value),
        $replacement
    )
);

Tomas's user avatar

Tomas

56.6k48 gold badges232 silver badges368 bronze badges

answered Dec 29, 2011 at 14:09

Deept Raghav's user avatar

Deept RaghavDeept Raghav

1,43013 silver badges14 bronze badges

5

If performance is an issue, one may consider not to create multiple functions within array_map(). Note that isset() is extremely fast, and this solutions does not call any other functions at all.

$replacements = array(
    'search1' => 'replace1',
    'search2' => 'replace2',
    'search3' => 'replace3'
);
foreach ($a as $key => $value) {
    if (isset($replacements[$value])) {
        $a[$key] = $replacements[$value];
    }
}

rmorse's user avatar

rmorse

7266 silver badges17 bronze badges

answered Sep 1, 2015 at 0:12

BurninLeo's user avatar

BurninLeoBurninLeo

4,1304 gold badges37 silver badges54 bronze badges

Try this function.

public function recursive_array_replace ($find, $replace, $array) {
    if (!is_array($array)) {
        return str_replace($find, $replace, $array);
    }

    $newArray = [];
    foreach ($array as $key => $value) {
        $newArray[$key] = recursive_array_replace($find, $replace, $value);
    }
    return $newArray;
}

Cheers!

Joshua's user avatar

Joshua

4,7642 gold badges30 silver badges44 bronze badges

answered Dec 29, 2011 at 14:13

Prasad Rajapaksha's user avatar

Prasad RajapakshaPrasad Rajapaksha

6,05210 gold badges36 silver badges52 bronze badges

1

$ar[array_search('green', $ar)] = 'value';

answered Mar 11, 2019 at 14:26

Douglas Comim's user avatar

2

Depending whether it’s the value, the key or both you want to find and replace on you could do something like this:

$array = json_decode( str_replace( $replace, $with, json_encode( $array ) ), true );

I’m not saying this is the most efficient or elegant, but nice and simple.

answered Sep 5, 2016 at 19:50

Dan - See Green's user avatar

1

What about array_walk() with callback?

$array = ['*pasta', 'cola', 'pizza'];
$search = '*';
$replace = '*';
array_walk($array,
    function (&$v) use ($search, $replace){
        $v = str_replace($search, $replace, $v);    
    }                                                                     
);  
print_r($array);

answered Sep 13, 2016 at 14:27

user3396065's user avatar

user3396065user3396065

5405 silver badges15 bronze badges

1

Based on Deept Raghav‘s answer, I created the follow solution that does regular expression search.

$arr = [
    'Array Element 1',
    'Array Element 2',
    'Replace Me',
    'Array Element 4',
];

$arr = array_replace(
    $arr,
    array_fill_keys(
        array_keys(
            preg_grep('/^Replace/', $arr)
        ),
        'Array Element 3'
    )
);

echo '<pre>', var_export($arr), '</pre>';

PhpFiddle: http://phpfiddle.org/lite/code/un7u-j1pt

answered Mar 4, 2016 at 22:45

waltzofpearls's user avatar

1

PHP 8, a strict version to replace one string value into another:

array_map(static fn (string $value): string => $value === $find ? $replace : $value, $array); 

An example — replace value foo by bar:

array_map(static fn (string $value): string => $value === 'foo' ? 'bar' : $value, $array);

answered Aug 9, 2021 at 20:38

Marek Gralikowski's user avatar

1

You can make full string matches without specifying the keys of qualifying values, by calling preg_replace() with a pattern containing start and end of string anchors (^, $). If your search term may contain characters which have a special meaning to the regex engine, then be sure to escape them with preg_quote() to avoid breakage. While regex is not entirely called for, regex offers some very convenient ways to tweak the search term handling. (Demo)

function array_replace_value(&$ar, $value, $replacement)
{
    $ar = preg_replace(
              '/^' . preg_quote($value, '/') . '$/',
              $replacement,
              $ar
          );
}

I might be more inclined to use array_map() with arrow function syntax so that global variables can be accessed within the custom function scope. (Demo)

$needle = 'foo';
$newValue = 'bar';

var_export(
    array_map(fn($v) => $v === $needle ? $newValue : $v, $array)
);

answered Dec 13, 2022 at 12:05

mickmackusa's user avatar

mickmackusamickmackusa

41.8k12 gold badges82 silver badges125 bronze badges

$ar = array(1,2,3,4,5,6,7,8);
$find = array(2,3);
$replace = array(13);

function update_bundle_package($ar,$find,$replace){
foreach ($find as $x => $y) {
    ///TO REMOVE PACKAGE
    if (($key = array_search($y, $ar)) !== false) {
        unset($ar[$key]);
    }
    ///TO REMOVE PACKAGE
}
$ar = array_merge($ar, $replace); 
}

answered Dec 22, 2022 at 8:34

pratik shourabh's user avatar

1

 <b>$green_key = array_search('green', $input); // returns the first key whose value is 'green'

$input[$green_key] = ‘apple’; // replace ‘green’ with ‘apple’

answered Dec 29, 2011 at 14:17

Muthu Krishnan's user avatar

Muthu KrishnanMuthu Krishnan

1,6642 gold badges10 silver badges15 bronze badges

2

I was looking for some standard PHP function to replace some value of an array with other, but surprisingly I haven’t found any, so I have to write my own:

function array_replace_value(&$ar, $value, $replacement)
{
    if (($key = array_search($ar, $value)) !== FALSE) {
        $ar[$key] = $replacement;
    }
}

But I still wonder — for such an easy thing there must already be some function for it! Or maybe much easier solution than this one invented by me?

Note that this function will only do one replacement. I’m looking for existing solutions that similarly replace a single occurrence, as well as those that replace all occurrences.

outis's user avatar

outis

74.4k21 gold badges149 silver badges219 bronze badges

asked Dec 29, 2011 at 14:05

Tomas's user avatar

12

Instead of a function that only replaces occurrences of one value in an array, there’s the more general array_map:

array_map(function ($v) use ($value, $replacement) {
    return $v == $value ? $replacement : $v;
}, $arr);

To replace multiple occurrences of multiple values using array of value => replacement:

array_map(function ($v) use ($replacement) {
    return isset($replacement[$v]) ? $replacement[$v] : $v;
}, $arr);

To replace a single occurrence of one value, you’d use array_search as you do. Because the implementation is so short, there isn’t much reason for the PHP developers to create a standard function to perform the task. Not to say that it doesn’t make sense for you to create such a function, if you find yourself needing it often.

answered Dec 29, 2011 at 14:19

outis's user avatar

outisoutis

74.4k21 gold badges149 silver badges219 bronze badges

5

While there isn’t one function equivalent to the sample code, you can use array_keys (with the optional search value parameter), array_fill and array_replace to achieve the same thing:

EDIT by Tomas: the code was not working, corrected it:

$ar = array_replace($ar,
    array_fill_keys(
        array_keys($ar, $value),
        $replacement
    )
);

Tomas's user avatar

Tomas

56.6k48 gold badges232 silver badges368 bronze badges

answered Dec 29, 2011 at 14:09

Deept Raghav's user avatar

Deept RaghavDeept Raghav

1,43013 silver badges14 bronze badges

5

If performance is an issue, one may consider not to create multiple functions within array_map(). Note that isset() is extremely fast, and this solutions does not call any other functions at all.

$replacements = array(
    'search1' => 'replace1',
    'search2' => 'replace2',
    'search3' => 'replace3'
);
foreach ($a as $key => $value) {
    if (isset($replacements[$value])) {
        $a[$key] = $replacements[$value];
    }
}

rmorse's user avatar

rmorse

7266 silver badges17 bronze badges

answered Sep 1, 2015 at 0:12

BurninLeo's user avatar

BurninLeoBurninLeo

4,1304 gold badges37 silver badges54 bronze badges

Try this function.

public function recursive_array_replace ($find, $replace, $array) {
    if (!is_array($array)) {
        return str_replace($find, $replace, $array);
    }

    $newArray = [];
    foreach ($array as $key => $value) {
        $newArray[$key] = recursive_array_replace($find, $replace, $value);
    }
    return $newArray;
}

Cheers!

Joshua's user avatar

Joshua

4,7642 gold badges30 silver badges44 bronze badges

answered Dec 29, 2011 at 14:13

Prasad Rajapaksha's user avatar

Prasad RajapakshaPrasad Rajapaksha

6,05210 gold badges36 silver badges52 bronze badges

1

$ar[array_search('green', $ar)] = 'value';

answered Mar 11, 2019 at 14:26

Douglas Comim's user avatar

2

Depending whether it’s the value, the key or both you want to find and replace on you could do something like this:

$array = json_decode( str_replace( $replace, $with, json_encode( $array ) ), true );

I’m not saying this is the most efficient or elegant, but nice and simple.

answered Sep 5, 2016 at 19:50

Dan - See Green's user avatar

1

What about array_walk() with callback?

$array = ['*pasta', 'cola', 'pizza'];
$search = '*';
$replace = '*';
array_walk($array,
    function (&$v) use ($search, $replace){
        $v = str_replace($search, $replace, $v);    
    }                                                                     
);  
print_r($array);

answered Sep 13, 2016 at 14:27

user3396065's user avatar

user3396065user3396065

5405 silver badges15 bronze badges

1

Based on Deept Raghav‘s answer, I created the follow solution that does regular expression search.

$arr = [
    'Array Element 1',
    'Array Element 2',
    'Replace Me',
    'Array Element 4',
];

$arr = array_replace(
    $arr,
    array_fill_keys(
        array_keys(
            preg_grep('/^Replace/', $arr)
        ),
        'Array Element 3'
    )
);

echo '<pre>', var_export($arr), '</pre>';

PhpFiddle: http://phpfiddle.org/lite/code/un7u-j1pt

answered Mar 4, 2016 at 22:45

waltzofpearls's user avatar

1

PHP 8, a strict version to replace one string value into another:

array_map(static fn (string $value): string => $value === $find ? $replace : $value, $array); 

An example — replace value foo by bar:

array_map(static fn (string $value): string => $value === 'foo' ? 'bar' : $value, $array);

answered Aug 9, 2021 at 20:38

Marek Gralikowski's user avatar

1

You can make full string matches without specifying the keys of qualifying values, by calling preg_replace() with a pattern containing start and end of string anchors (^, $). If your search term may contain characters which have a special meaning to the regex engine, then be sure to escape them with preg_quote() to avoid breakage. While regex is not entirely called for, regex offers some very convenient ways to tweak the search term handling. (Demo)

function array_replace_value(&$ar, $value, $replacement)
{
    $ar = preg_replace(
              '/^' . preg_quote($value, '/') . '$/',
              $replacement,
              $ar
          );
}

I might be more inclined to use array_map() with arrow function syntax so that global variables can be accessed within the custom function scope. (Demo)

$needle = 'foo';
$newValue = 'bar';

var_export(
    array_map(fn($v) => $v === $needle ? $newValue : $v, $array)
);

answered Dec 13, 2022 at 12:05

mickmackusa's user avatar

mickmackusamickmackusa

41.8k12 gold badges82 silver badges125 bronze badges

$ar = array(1,2,3,4,5,6,7,8);
$find = array(2,3);
$replace = array(13);

function update_bundle_package($ar,$find,$replace){
foreach ($find as $x => $y) {
    ///TO REMOVE PACKAGE
    if (($key = array_search($y, $ar)) !== false) {
        unset($ar[$key]);
    }
    ///TO REMOVE PACKAGE
}
$ar = array_merge($ar, $replace); 
}

answered Dec 22, 2022 at 8:34

pratik shourabh's user avatar

1

 <b>$green_key = array_search('green', $input); // returns the first key whose value is 'green'

$input[$green_key] = ‘apple’; // replace ‘green’ with ‘apple’

answered Dec 29, 2011 at 14:17

Muthu Krishnan's user avatar

Muthu KrishnanMuthu Krishnan

1,6642 gold badges10 silver badges15 bronze badges

2

Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Модификация

JS: Массивы

Примитивные типы данных, с которыми мы работали до сих пор, невозможно изменить. Любые функции и методы над ними возвращают новые значения, но не могут ничего сделать со старым.

const name = 'Hexlet';
name.toUpperCase(); // 'HEXLET'
// Значение name не поменялось
console.log(name); // 'Hexlet'

С массивами это правило не работает. Массивы могут меняться: увеличиваться, уменьшаться, изменять значения по индексам. Ниже мы разберем все эти операции.

Изменение элементов массива

Синтаксис изменения элемента массива практически такой же, как и при обращении к элементу массива. Разница лишь в наличии присваивания:

const animals = ['cats', 'dogs', 'birds'];
// Меняется первый элемент массива
animals[0] = 'horses';
console.log(animals); // => [ 'horses', 'dogs', 'birds' ]

Самое неожиданное в данном коде – изменение константы. Константы в JavaScript не совсем то, как мы себе это представляли раньше. Константы хранят ссылку на данные (подробнее об этом в следующих уроках), а не сами данные. Это значит что менять данные можно, но нельзя заменить ссылку. Технически это значит, что мы не можем заменить все значение константы целиком:

const animals = ['cats', 'dogs', 'birds'];
// Меняем данные, а сам массив остался тем же
// Такой код работает
animals[2] = 'fish';
console.log(animals); // => [ 'cats', 'dogs', 'fish' ]

// Произойдет ошибка, так как здесь идет замена константы
animals = ['fish', 'cats'];
// Uncaught TypeError: Assignment to constant variable.

Добавление элемента в массив

Метод push() добавляет элемент в конец массива:

const animals = ['cats', 'dogs', 'birds'];
animals.push('horses');

// массив animals изменен — стал больше
console.log(animals); // => [ 'cats', 'dogs', 'birds', 'horses' ]

// строка 'horses' была добавлена в конец массива (индекс = 3)
console.log(animals[3]); // => 'horses'

Метод unshift() добавляет элемент в начало массива:

const animals = ['cats', 'dogs', 'birds'];
animals.unshift('horses');

// массив animals изменен — стал больше
console.log(animals); // => [ 'horses', 'cats', 'dogs', 'birds' ]

// строка 'horses' была добавлена в начало массива (индекс = 0)
console.log(animals[0]); // => 'horses'

Иногда индекс добавления известен сразу и в таком случае добавление работает так же как и изменение:

const animals = ['cats', 'dogs', 'birds'];
animals[3] = 'horses';
console.log(animals); // => [ 'cats', 'dogs', 'birds', 'horses' ]

Удаление элемента из массива

Удалить элемент из массива можно с помощью специальной конструкции delete: delete arr[index].

Пример:

const animals = ['cats', 'dogs', 'birds'];
delete animals[1]; // удаляем элемент под индексом 1
console.log(animals); // => [ 'cats', <1 empty item>, 'birds' ]

Этот способ обладает рядом недостатков, завязанных на особенности внутренней организации языка JavaScript. Например, после такого удаления, можно с удивлением заметить, что размер массива не изменился:

Понравилась статья? Поделить с друзьями:
  • Как изменить buffer size fl studio
  • Как изменить apple id на макбуке
  • Как изменить bssid роутера
  • Как изменить apple id на айфоне se 2020
  • Как изменить bsod