Как найти элемент массива по его значению

(PHP 4 >= 4.0.5, PHP 5, PHP 7, PHP 8)

array_searchSearches the array for a given value and returns the first corresponding key if successful

Description

array_search(mixed $needle, array $haystack, bool $strict = false): int|string|false

Parameters

needle

The searched value.

Note:

If needle is a string, the comparison is done
in a case-sensitive manner.

haystack

The array.

strict

If the third parameter strict is set to true
then the array_search() function will search for
identical elements in the
haystack. This means it will also perform a
strict type comparison of the
needle in the haystack,
and objects must be the same instance.

Return Values

Returns the key for needle if it is found in the
array, false otherwise.

If needle is found in haystack
more than once, the first matching key is returned. To return the keys for
all matching values, use array_keys() with the optional
search_value parameter instead.

Warning

This function may
return Boolean false, but may also return a non-Boolean value which
evaluates to false. Please read the section on Booleans for more
information. Use the ===
operator for testing the return value of this
function.

Examples

Example #1 array_search() example


<?php
$array
= array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array); // $key = 1;
?>

See Also

  • array_keys() – Return all the keys or a subset of the keys of an array
  • array_values() – Return all the values of an array
  • array_key_exists() – Checks if the given key or index exists in the array
  • in_array() – Checks if a value exists in an array

turabgarip at gmail dot com

6 years ago


About searcing in multi-dimentional arrays; two notes on "xfoxawy at gmail dot com";

It perfectly searches through multi-dimentional arrays combined with array_column() (min php 5.5.0) but it may not return the values you'd expect.

<?php array_search($needle, array_column($array, 'key')); ?>

Since array_column() will produce a resulting array; it won't preserve your multi-dimentional array's keys. So if you check against your keys, it will fail.

For example;

<?php
$people
= array(
 
2 => array(
   
'name' => 'John',
   
'fav_color' => 'green'
 
),
 
5=> array(
   
'name' => 'Samuel',
   
'fav_color' => 'blue'
 
)
);
$found_key = array_search('blue', array_column($people, 'fav_color'));
?>

Here, you could expect that the $found_key would be "5" but it's NOT. It will be 1. Since it's the second element of the produced array by the array_column() function.

Secondly, if your array is big, I would recommend you to first assign a new variable so that it wouldn't call array_column() for each element it searches. For a better performance, you could do;

<?php
$colors
= array_column($people, 'fav_color');
$found_key = array_search('blue', $colors);
?>


cue at openxbox dot com

19 years ago


If you are using the result of array_search in a condition statement, make sure you use the === operator instead of == to test whether or not it found a match.  Otherwise, searching through an array with numeric indicies will result in index 0 always getting evaluated as false/null.  This nuance cost me a lot of time and sanity, so I hope this helps someone.  In case you don't know what I'm talking about, here's an example:

<?php

$code
= array("a", "b", "a", "c", "a", "b", "b"); // infamous abacabb mortal kombat code :-P

// this is WRONG

while (($key = array_search("a", $code)) != NULL)

{

// infinite loop, regardless of the unset

unset($code[$key]);

}
// this is _RIGHT_

while (($key = array_search("a", $code)) !== NULL)

{

// loop will terminate

unset($code[$key]);

}

?>


stefano@takys dot it

12 years ago


for searching case insensitive better this:

<?php

array_search
(strtolower($element),array_map('strtolower',$array));

?>


RichGC

17 years ago


To expand on previous comments, here are some examples of
where using array_search within an IF statement can go
wrong when you want to use the array key thats returned.

Take the following two arrays you wish to search:

<?php
$fruit_array
= array("apple", "pear", "orange");
$fruit_array = array("a" => "apple", "b" => "pear", "c" => "orange");

if (

$i = array_search("apple", $fruit_array))
//PROBLEM: the first array returns a key of 0 and IF treats it as FALSEif (is_numeric($i = array_search("apple", $fruit_array)))
//PROBLEM: works on numeric keys of the first array but fails on the secondif ($i = is_numeric(array_search("apple", $fruit_array)))
//PROBLEM: using the above in the wrong order causes $i to always equal 1if ($i = array_search("apple", $fruit_array) !== FALSE)
//PROBLEM: explicit with no extra brackets causes $i to always equal 1if (($i = array_search("apple", $fruit_array)) !== FALSE)
//YES: works on both arrays returning their keys
?>


thinbegin at gmail dot com

5 years ago


Despite PHP's amazing assortment of array functions and juggling maneuvers, I found myself needing a way to get the FULL array key mapping to a specific value. This function does that, and returns an array of the appropriate keys to get to said (first) value occurrence.

function array_recursive_search_key_map($needle, $haystack) {
    foreach($haystack as $first_level_key=>$value) {
        if ($needle === $value) {
            return array($first_level_key);
        } elseif (is_array($value)) {
            $callback = array_recursive_search_key_map($needle, $value);
            if ($callback) {
                return array_merge(array($first_level_key), $callback);
            }
        }
    }
    return false;
}

usage example:
-------------------

$nested_array = $sample_array = array(
    'a' => array(
        'one' => array ('aaa' => 'apple', 'bbb' => 'berry', 'ccc' => 'cantalope'),
        'two' => array ('ddd' => 'dog', 'eee' => 'elephant', 'fff' => 'fox')
    ),
    'b' => array(
        'three' => array ('ggg' => 'glad', 'hhh' => 'happy', 'iii' => 'insane'),
        'four' => array ('jjj' => 'jim', 'kkk' => 'kim', 'lll' => 'liam')
    ),
    'c' => array(
        'five' => array ('mmm' => 'mow', 'nnn' => 'no', 'ooo' => 'ohh'),
        'six' => array ('ppp' => 'pidgeon', 'qqq' => 'quail', 'rrr' => 'rooster')
    )
);

$search_value = 'insane';

$array_keymap = array_recursive_search_key_map($search_value, $nested_array);

var_dump($array_keymap);
// Outputs:
// array(3) {
// [0]=>
//  string(1) "b"
//  [1]=>
//  string(5) "three"
//  [2]=>
//  string(3) "iii"
//}

----------------------------------------------

But again, with the above solution, PHP again falls short on how to dynamically access a specific element's value within the nested array. For that, I wrote a 2nd function to pull the value that was mapped above.

function array_get_nested_value($keymap, $array)
{
    $nest_depth = sizeof($keymap);
    $value = $array;
    for ($i = 0; $i < $nest_depth; $i++) {
        $value = $value[$keymap[$i]];
    }

    return $value;
}

usage example:
-------------------
echo array_get_nested_value($array_keymap, $nested_array);   // insane


opencart dot ocfilter at gmail dot com

1 year ago


Be careful!

<?php

var_dump

(array_search('needle', [ 0 => 0 ])); // int(0) (!)var_dump(array_search('needle', [ 0 => 0 ], true)); // bool(false)?>

But, in php 8

<?php

var_dump

(array_search('needle', [ 0 => 0 ])); // bool(false)?>


maciej at speccode dot com

7 years ago


FYI, remember that strict mode is something that might save you hours.

If you're searching for a string and you have a "true" boolean on the way - you will get it as result (first occurrence). Example below:

<?php

$arr

= [
   
'foo'    => 'bar',
   
'abc'    => 'def',
   
'bool'   => true,
   
'target' => 'xyz'
];var_dump( array_search( 'xyz', $arr ) ); //bool
var_dump( array_search( 'xyz', $arr, true ) ); //target?>


azaozz, gmail

14 years ago


Expanding on the comment by hansen{}cointel.de:

When searching for a string and the array contains 0 (zero), the string is casted to (int) by the type-casting which is always 0 (perhaps the opposite is the proper behaviour, the array value 0 should have been casted to string). That produces unexpected results if strict comparison is not used:

<?php
$a
= array(0, "str1", "str2", "str3");
echo
"
str1 = "
.array_search("str1", $a).",
str2 = "
.array_search("str2", $a).",
str3 = "
.array_search("str3", $a).",

str1 strict = "

.array_search("str1", $a, true).",
str2 strict = "
.array_search("str2", $a, true).",
str3 strict = "
.array_search("str3", $a, true);
?>

This will return:
str1 = 0, str2 = 0, str3 = 0, str1 strict = 1, str2 strict = 2, str3 strict = 3


codeslinger at compsalot dot com

13 years ago


one thing to be very aware of is that array_search() will fail if the needle is a string and the array itself contains values that are mixture of numbers and strings.  (or even a string that looks like a number)

The problem is that unless you specify "strict" the match is done using ==    and in that case any string will match a numeric value of zero which is not what you want.

-----

also, php can lookup an index pretty darn fast.  for many scenarios, it is practical to maintain multiple arrays, one in which the index of the array is the search key and the normal array that contains the data.

<?php

  $normal

[$index] = array('key'=>$key, 'data'=>'foo');

 
$inverse[$key] = $index;
//very fast lookup, this beats any other kind of search
if (array_key_exists($key, $inverse))

  {

   
$index = $inverse[$key];

    return
$normal[$index];

  }
?>


n-regen

14 years ago


If you only know a part of a value in an array and want to know the complete value, you can use the following function:
<?php
function array_find($needle, $haystack)
{
   foreach (
$haystack as $item)
   {
      if (
strpos($item, $needle) !== FALSE)
      {
         return
$item;
         break;
      }
   }
}
?>
The function returns the complete first value of $haystack that contains $needle.

andreas dot damm at maxmachine dot de

15 years ago


Combining syntax of array_search() and functionality of array_keys() to get all key=>value associations of an array with the given search-value:
<?php
function array_search_values( $m_needle, $a_haystack, $b_strict = false){
    return
array_intersect_key( $a_haystack, array_flip( array_keys( $a_haystack, $m_needle, $b_strict)));
}
?>

Usage:
<?php
$array1
= array( 'pre'=>'2', 1, 2, 3, '1', '2', '3', 'post'=>2);
print_r( array_search_values( '2', $array1));
print_r( array_search_values( '2', $array1, true));
print_r( array_search_values( 2, $array1, true));
?>

Will return:
array(4) {
    ["pre"] =>
    string(1) "2"
    [1] =>
    int(2)
    [4] =>
    string(1) "2"
    ["post"] =>
    int(2)
}
array(2) {
    ["pre"] =>
    string(1) "2"
    [4] =>
    string(1) "2"
}
array(2) {
    [1] =>
    int(2)
    ["post"] =>
    int(2)
}

yasien dot dwieb at gmail dot com

3 years ago


Beware when using array_search to a mix of string and integer where prefixes of keys may collide, as in my case I have encountered the following situation:

Assume you have the following array:
<?php
$arr
= [
          
1 => 'index 0',
          
2 => 'index 1',
          
3 => 'index 2',
          
'3anothersuffix' => 'index 3'
];$index1 = array_search('3', array_keys($arr)); // 2
$index2 = array_search('3anothersuffix', array_keys($arr)); //2
?>

$index1 and $index2 will be the same

after using strict type search:

<?php
$index1
= array_search('3', array_keys($arr), true); // false
$index2 = array_search('3anothersuffix', array_keys($arr), true);  //3
?>

it will not find $index1 at all while returning a correct value for $index2;


stooshie at gmail dot com

11 years ago


Example of a recursive binary search that returns the index rather than boolean.
<?php
// returns the index of needle in haystack
function binSearch($needle, $haystack)
{
   
// n is only needed if counting depth of search
   
global $n;
   
$n++;
   
// get the length of passed array
   
$l = count($haystack);
   
// if length is 0, problem
   
if($l <= 0)
    {
        return -
1;
    }
   
// get the mid element
   
$m = (($l+($l%2))/2);
   
// if mid >= length (e.g. l=1)
   
if($m >= $l)
    {
       
$m = $m-1;
    }
   
// get the indexed element to compare to the passed element and branch accordingly
   
$compare = $haystack[$m];
    switch(
true)
    {
        case(
$compare>$needle):
        {
           
// recurse on the lower half
           
$new_haystack = array_slice($haystack, 0, $m);
           
$c = count($new_haystack);
           
$r = binSearch($needle, $new_haystack);
           
// return current index - (length of lower half - found index in lower half)
           
return $m - ($c - $r);
            break;
        }
        case(
$compare<$needle):
        {
           
// recurse on the upper half
           
$new_haystack = array_slice($haystack, $m, ($l-$m));
           
$c = count($new_haystack);
           
$r = binSearch($needle, $new_haystack);
           
// return current position + found index in upper half
           
return $m + $r;
            break;
        }
        case(
$compare==$needle):
        {
           
// found it, so return index
           
return $m;
            break;
        }
    }
}
?>

helenadeus at gmail dot com

14 years ago


I was trying to use array_search to retrieve all the values that match a given needle, but it turns out only the first match key is returned. I built this little function, which works just like array_search, but returns all the keys that match a given needle instead. The output is an array.

<?php

$haystack

= array('a','b','a','b');$needle = 'a';print_r(array_search_all($needle, $haystack));//Output will be
// Array
// (
//         [0]=>1
//         [1]=>3
// )
function array_search_all($needle, $haystack)
{
#array_search_match($needle, $haystack) returns all the keys of the values that match $needle in $haystackforeach ($haystack as $k=>$v) {

            if(

$haystack[$k]==$needle){$array[] = $k;
        }
    }
    return (
$array);

    }

?>


nordseebaer at gmx dot de

3 years ago


It's really important to check the return value is not false! I used array_search() to determine the index of an value to unset this value and then realized that $arr[false] === $arr[0] !

<?php
$arr
= ['apple', 'banana'];var_dump($arr[0] === 'apple'); // true
var_dump($arr[false] === $arr[0]); // true
var_dump($arr[false] === 'apple'); // trueunset($arr[array_search('banana', $arr)]); //index = 1
var_dump($arr);// result
//   array(1) {
//     [0]=>
//     string(5) "apple"
//   }
unset($arr[array_search('peach', $arr)]); //not found, result is false
var_dump($arr);// result
//   array(0) {
//   }
// because $arr[false] === $arr[0]
?>

So always check the return of array_search!


kermes [at] thesevens [dot] net

15 years ago


A variation of previous searches that returns an array of keys that match the given value:

<?php
function array_ksearch($array, $str)
{
   
$result = array();
    for(
$i = 0; $i < count($array); next($array), $i++)
        if(
strtolower(current($array)) == strtolower($str))
           
array_push($result, key($array);

        return

$result;
}
?>

Usage would be as follows:
<?php
$testArray
= array('one' => 'test1', 'two' => 'test2', 'three' => 'test1', 'four' => 'test2', 'five' => 'test1');
   
print_r(array_ksearch($testArray, 'test1'));
?>


Перевод статьи 4 Methods to Search Through Arrays in JavaScript.

В JavaScript существует несколько довольно эффективных способов поиска элементов в массивах. В самом простом случае вы всегда можете прибегнуть помощи базового цикла for, однако в стандарте ES6 + предусмотрено гораздо большое число методов, предназначенных для циклического перебора элементов массива и поиска среди них тех, что нам нужны.

С таким количеством различных методов поиска и перебора, какой из них рациональнее использовать в каждом из отдельных случаев? Например, в ходе поиска в массиве вы хотите просто узнать, находится ли нужный нам элемент в массиве вообще? А может вам нужен только индекс этого элемента или же он сам?

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

Далее мы рассмотрим следующие методы массивов Array:

  • Array.includes
  • Array.find
  • Array.indexOf
  • Array.filter

includes

const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];

alligator.includes("thick scales"); // вернет true

Метод .include() возвращает логическое значение и идеально подходит для определения факта наличия искомого элемента в массиве. То есть он просто отвечает true или false. Ниже представлен общий вид его синтаксиса:

arr.includes(valueToFind, [fromIndex]);

Как мы можем заметить, этот метод принимает только один обязательный параметр — valueToFind. Это значение затем используется для сопоставления со значениями элементов массива arr. Необязательный параметр fromIndex — это целое число, предписывающее с какого индекса будет начат поиск. По умолчанию это значение равно 0, и поэтому поиск будет осуществляться по всему массиву.

Итак, поскольку в нашем примере выше элемент, с которого начнется поиск имеет индекс 0, то возвращается true. А вот следующая инструкция вернет ложное значение: alligator.include ("thick scales", 1);, так как в этом случае поиск начинается с элемента с индексом 1.

Теперь подробнее рассмотрим несколько важных деталей, на которые стоит обратить внимание. Первое — метод .includes() использует строгое сравнение. Это означает, с учетом уже рассмотренного нами выше примера, что следующая инструкция: alligator.includes('80'); вернет false . Это происходит потому, что хотя вычисление логического выражения 80 == '80' приведет к получению результата true, однако, так как в нашем случае используется строгое сравнение, то 80 === '80' вернет false, то есть значения с разными типами никогда не будут проходить эту проверку.

find

Чем же метод .find() отличается от .include()? Так если бы мы в нашем примере выше изменили название метода «include» на «find», то получили бы следующую ошибку:

Uncaught TypeError: thick scales is not a function

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

Таким образом, и хотя следующая инструкция будет работать корректно: alligator.find (() => 'thick scale');, но вы, вероятно, захотите добавить в качестве функции-аргумента свой собственный оператор сравнения для того, чтобы он возвращал что-то нужное нам.

const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];

alligator.find(el => el.length < 12); // вернет '4 foot tail'

Эта простая функция, передаваемая нашему методу .find(), проверяет каждый элемент массива, доступный по присваиваемому псевдониму el. Перебор элементов прекращается, когда находится первое совпадение. В нашем случае возвращается true для такого элемента массива, у которого есть свойство length, и его значение менее 12 (напомним, что числа не имеют свойства length). Конечно же, вы можете сделать эту функцию настолько сложной, насколько вам это необходимо, и возвращаемое ей значение соответствовало вашим требованиям.

Заметьте, что результат выполнения нашего кода, из примера выше, не возвращает true, как это было ранее. Это происходит потому, что метод .find() не возвращает логическое значение, а возвращает первый элемент, который соответствует критерию, определенному в функции. Если соответствующего элемента, который соответствует критериям, определенным в вашей функции, то метод вернет undefined. Также обратите внимание, что он возвращает только первый элемент, соответствующий критерию. Таким образом если в массиве более одного элемента, соответствующего критерию в функции, то все равно будет возвращаться только первый, соответствующий критерию в функции. В нашем примере, если бы после элемента со значением 4 foot tail, был другой со значением, в виде строки длиной менее 12 символов, то это ни как не изменило бы наш результат.

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

alligator.find((el, idx) => typeof el === "string" && idx === 2); // вернет '4 foot tall'

И так в нашем массиве три различных элемента, которые удовлетворяют условию (typeof el === 'string'). Если бы это было наше единственное условие, то наш скрипт вернул бы первый элемент массива: thick scales. Но дело в том, что только у одного из элементов нашего массива индекс равен 2 и это элемент со значением 4 foot tall.

Говоря об индексах элементов, схожим методом перебора элементов массива является .findIndex(). Этот метод тоже в качестве параметра принимает функцию, но, как вы уже можете догадаться, он возвращает индекс соответствующего ее критерию элемента, а не его значение.

indexOf

const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];

alligator.indexOf("rounded snout"); // будет возвращено 3

Как и .include(), метод .indexOf() использует строгое сравнение, а не функцию, как мы это видели рассматривая особенности использования метода .find(). Но, в отличие от метода include(), он возвращает индекс элемента, а не логическое значение. Также вы можете указать, с какого индекса в массиве начинать поиск.

Лично я считаю, что метод .indexOf() может оказаться весьма полезен. Он позволяет легко определить местоположение искомого элемент в массиве, а также проверить присутствует ли в нем элемент с указанным значением. Как же нам понять существует ли указанный элемент в массиве или нет? По сути, мы можем легко определить это, то есть в случае его наличия метод вернет положительное число, и если нет — то -1, что указывает на его отсутствие.

alligator.indexOf("soft and fluffy"); // вернет -1
alligator.indexOf(80); // вернет 1
alligator.indexOf(80, 2); // вернет -1

И, как вы можете видеть, хотя мы могли бы получить методы .find() или .findIndex(), чтобы предоставить нам ту же информацию, писать это намного меньше. Нам не нужно выписывать функцию для сравнения, так как она уже есть в методе .indexOf().

Теперь мы знаем что, метод indexOf() возвращает индекс первого элемента, соответствующего нашему критерию. Тем не менее JavaScript предоставляет нам альтернативный метод поиска элемента в массиве: .lastIndexOf(). Как вы можете догадаться, он делает то же самое, что и метод indexOf(), но начинает поиск с последнего элемента массива в обратном направлении. У этого метода вы также можете указать второй параметр, но помните, что порядок индексов массива остается прежним, не смотря на обратное направление его перебора.

const alligator = ["thick scales", 80, "4 foot tail", "rounded snout", 80];

alligator.indexOf(80); // вернет 1
alligator.lastIndexOf(80); // вернет 4
alligator.indexOf(80, 2); // вернет 4
alligator.lastIndexOf(80, 4); // вернет 4
alligator.lastIndexOf(80, 3); // вернет 1

filter

const alligator = ["thick scales", 80, "4 foot tail", "rounded snout", 80];

alligator.filter(el => el === 80); //вернет [80, 80]

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

Говоря о методе .filter() важно понимать, что он возвращает все элементы, соответствующие вашему критерию, то есть все элементы, которые вы хотите “отфильтровать”.

Заключение

В самом простом случае, когда мне необходимо найти в массиве какое-либо значение я использую метод .find(), но, как вы могли заметить, применение какого-либо метода зависит от конкретного случая.

Вам нужно только узнать существует ли в массиве элемент с определенным значением? Используйте метод .includes().

Вам нужно получить сам элемент массива, значение которого соответствует определенному критерию? Используйте методы .find() или .filter() для получения элементов.

Вам нужно найти индекс какого-либо элемента? Используйте методы .indexOf() или .findIndex() для использования более сложного критерия поиска.

Массивы в примерах, которые мы здесь рассмотрели на самом деле простые. Однако на практике вы можете столкнуться с более сложными случаями, например, с массивами объектов. Вот несколько простых примеров практик, которые вам могут пригодится, для работы с массивами, состоящими из вложенных объектов:

const jungle = [
  { name: "frog", threat: 0 },
  { name: "monkey", threat: 5 },
  { name: "gorilla", threat: 8 },
  { name: "lion", threat: 10 }
];

// разберем объект, перед использованием методов поиска .include () или .indexOf ()
const names = jungle.map(el => el.name); // веренет ['frog', 'monkey', 'gorilla', 'lion']
console.log(names.includes("gorilla")); // веренет true
console.log(names.indexOf("lion")); // веренет 3 - что будет соответствовать верному положению элемента, при условии, что сортировка нового массива names не проводилась


// methods we can do on the array of objects
console.log(jungle.find(el => el.threat == 5)); // веренет объект - {name: "monkey", threat: 5}
console.log(jungle.filter(el => el.threat > 5)); // вернет массив - [{name: "gorilla", threat: 8}, {name: 'lion', threat: 10}]

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

Содержание

  • 1 Array.includes() — есть ли элемент в массиве
  • 2 Array.indexOf() — индекс элемента в массиве
  • 3 Array.find() — найти элемент по условию
  • 4 Array.findIndex() — найти индекс элемента в массиве
  • 5 Поиск всех совпадений в массиве
  • 6 Поиск в массиве объектов
  • 7 Заключение

Для поиска по массиву в JavaScript существует несколько методов прототипа Array, не считая что поиск можно выполнить и методами для перебора массива и в обычном цикле.

Итак, мы сегодня рассмотрим следующие варианты:

  • Array.includes()
  • Array.indexOf()
  • Array.find()
  • Array.findIndex()
  • Array.filter()
  • Array.forEach()

Array.includes() — есть ли элемент в массиве

Данный метод ищет заданный элемент и возвращает true или false, в зависимости от результата поиска. Принимает два параметра:

  • element — то, что мы будем искать
  • fromIndex (необязательный) — с какого индекса начинать поиск. По умолчанию с 0.
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry'];

console.log(arr.includes('Apple')); // true
console.log(arr.includes('Apple', 1)); // false

Как видно из примера выше, в первом случае мы получим true, т.к. начали с нулевого элемента массива. Во втором случае мы передали второй параметр — индекс, с которого нужно начать поиск — и получили false, т.к. дальше элемент не был найден.

Array.indexOf() — индекс элемента в массиве

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

Также принимает два параметра:

  • element — элемент, который мы будем искать
  • fromIndex (необязательный) — с какого индекса начинать поиск. По умолчанию с 0.
const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];

console.log(arr.indexOf('Apple')); // 0
console.log(arr.indexOf('Apple', 1)); // 4
console.log(arr.indexOf('Orange', 2)); // -1

Как видно из примера выше, в первом случае мы получаем 0, т.к. сразу нашли первый элемент массива (первое совпадение, дальше поиск уже не выполняется). Во втором случае 4, т.к. начали поиск с индекса 1 и нашли следующее совпадение. В третьем примере мы получили результат -1, т.к. поиск начали с индекса 2, а элемент Orange в нашем массиве под индексом 1.

Так как данный метод возвращает индекс или -1, мы можем присвоить результат в переменную для дальнейшего использования:

const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
const index = arr.indexOf('Lemon');

if (index !== -1) {
    // сделать что-то
}

Чтобы произвести какие-то действия над найденным элементом массива, мы можем использовать следующий синтаксис:

const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
const index = arr.indexOf('Lemon');

arr[index] = 'Lime'; // заменяем найденный элемент
console.log(arr)ж // ['Apple', 'Orange', 'Lime', 'Cherry', 'Apple']

Примеры использования данного метода вы можете также найти в посте про удаление элемента из массива

Array.find() — найти элемент по условию

Данный метод callback и thisArg в качестве аргументов и возвращает первое найденное значение.

Callback принимает несколько аргументов:
item — текущий элемент массива
index — индекс текущего элемента
currentArray — итерируемый массив

Пример использования:

const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];
  
const apple = arr.find(item => item === 'Apple');

console.log(apple); // Apple

Данный метод полезен тем, что мы можем найти и получить сразу и искомый элемент, и его index

const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];

let indexOfEl;
const apple = arr.find((item, index) => {
  if (item === 'Apple') {
    indexOfEl = index;
    return item;
  }
});

console.log(apple, indexOfEl); // Apple 0

Также работа кода прекратиться как только будет найден нужный элемент и второй элемент (дубликат) не будет найден.

В случае если ничего не найдено будет возвращен undefined.

Array.findIndex() — найти индекс элемента в массиве

Этот метод похож на метод find(), но возвращать будет только индекс элемента, который соответствует требованию. В случае, если ничего не найдено, вернет -1

const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];

const index = arr.findIndex(item => item === 'Apple');

console.log(index); // 0

Ну и по аналогии с предыдущим методом, поиск завершается после первого совпадения.

Поиск всех совпадений в массиве

Метод filter() кроме всего остального также можно использовать для поиска по массиву. Предыдущие методы останавливаются при первом соответствии поиска, а данный метод пройдется по массиву до конца и найдет все элементы. Но данный метод вернет новый массив, в который войдут все элементы соответствующие условию.

const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];

const filteredArr = arr.filter(item => item === 'Apple');

console.log(filteredArr); // ['Apple', 'Apple']
console.log(arr); // ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];

Как видите из примера выше, первоначальный массив не будет изменен.

Подробнее про метод JS filter() можете прочитать в этом посте.

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

const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];

let indexes = [];
arr.forEach((item, index) => {
  if (item === 'Apple') indexes.push(index)
});

console.log(indexes); // [0, 4]

В массив indexes мы получили индексы найденных элементов, это 0 и 4 элементы. Также в зависимости от вашей необходимости, можно создать объект, где ключом будет индекс, а значением сам элемент:

const arr = ['Apple', 'Orange', 'Lemon', 'Cherry', 'Apple'];

let arrObjMap = {};
arr.forEach((item, index) => {
  if (item === 'Apple') {
    arrObjMap[index] = item;
  }
});

console.log(arrObjMap); // {0: 'Apple', 4: 'Apple'}

Поиск в массиве объектов

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

Первый способ. С использованием метода map для массива

const arr = [
    { name: 'Ben', age: 21 },
    { name: 'Clif', age: 22 },
    { name: 'Eric', age: 18 },
    { name: 'Anna', age: 27 },
];

const index = arr.map(item => item.name).indexOf('Anna');


console.log(index); //3
console.log(arr[index]); // {name: 'Anna', age: 27}

В данном случае по массиву arr мы проходим и на каждой итерации из текущего элемента (а это объект со свойствами name и age) возвращаем имя человека в новый массив и сразу же выполняем поиск по новому массиву на имя Anna. При совпадении нам будет возвращен индекс искомого элемента в массиве.

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

const index = arr.findIndex(item => item.name === 'Anna');

console.log(index); //3
console.log(arr[index]); // {name: 'Anna', age: 27}

Заключение

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

Ваши вопросы и комментарии:

Array.prototype.find()

Метод find() возвращает первый элемент предоставленного массива, который удовлетворяет предоставленной функции тестирования. Если никакие значения не удовлетворяют функции тестирования, возвращается значение undefined .

Try it

  • Если вам нужен индекс найденного элемента в массиве, используйте findIndex() .
  • Если вам нужно найти индекс значения , используйте indexOf() . (Это похоже на findIndex() , но проверяет каждый элемент на равенство со значением вместо использования функции проверки.)
  • Если вам нужно узнать, существует ли значение в массиве, используйте includes() . Опять же, он проверяет каждый элемент на равенство со значением вместо использования функции проверки.
  • Если вам нужно найти, удовлетворяет ли какой-либо элемент предоставленной функции тестирования, используйте some() .

Syntax

find((element) => {  } )
find((element, index) => {  } )
find((element, index, array) => {  } )


find(callbackFn)
find(callbackFn, thisArg)


find(function(element) {  })
find(function(element, index) {  })
find(function(element, index, array){  })
find(function(element, index, array) {  }, thisArg)

Parameters

callbackFn

Функция для выполнения над каждым значением в массиве.

Функция вызывается со следующими аргументами:

element

Текущий элемент в массиве.

index

Индекс (позиция)текущего элемента в массиве.

array

Массив , что find была призвана.

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

thisArgOptional

Объект для использования в качестве this внутри callbackFn .

Return value

Первый элемент в массиве, который удовлетворяет предоставленной функции тестирования. В противном случае возвращается undefined

Description

Метод find выполняет функцию callbackFn один раз для каждого индекса массива, пока callbackFn не вернет истинное значение. Если это так, find немедленно возвращает значение этого элемента. В противном случае find возвращает значение undefined .

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

Если thisArg параметр при условии , чтобы find , он будет использоваться в качестве this значения внутри каждого вызова callbackFn . Если он не указан, используется undefined .

Метод find не изменяет массив, в котором он вызывается, но функция, предоставленная callbackFn , может. Если это так, элементы, обрабатываемые функцией find , устанавливаются перед первым вызовом callbackFn . Следовательно:

  • callbackFn не будет посещать какие-либо элементы, добавленные в массив после начала вызова find .
  • Элементы, которые назначены индексам, которые уже посещены, или индексам за пределами диапазона, callbackFn не будут посещены .
  • Если существующий, еще не посещенный элемент массива изменяется с помощью callbackFn , его значение, переданное в callbackFn , будет значением в то время, когда find посещает индекс этого элемента.
  • Элементы, которые были deleted , по-прежнему посещаются.

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

Examples

Найти объект в массиве по одному из его свойств

const inventory = [
  {name: 'apples', quantity: 2},
  {name: 'bananas', quantity: 0},
  {name: 'cherries', quantity: 5}
];

function isCherries(fruit) {
  return fruit.name === 'cherries';
}

console.log(inventory.find(isCherries));

Использование стрелочной функции и деструктуризации

const inventory = [
  {name: 'apples', quantity: 2},
  {name: 'bananas', quantity: 0},
  {name: 'cherries', quantity: 5}
];

const result = inventory.find(({ name }) => name === 'cherries');

console.log(result) 

Найти простое число в массиве

В следующем примере выполняется поиск элемента в массиве, который является простым числом (или возвращается undefined , если простого числа нет):

function isPrime(element, index, array) {
  let start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

console.log([4, 6, 8, 12].find(isPrime)); 
console.log([4, 5, 8, 12].find(isPrime)); 

Следующие примеры показывают , что не существует , а удаленные элементы будут посещенных и что значение передается функции обратного вызова их значение при посещении:

const array = [0,1,,,,5,6];


array.find((value, index) => {
  console.log('Visited index ', index, ' with value ', value);
});


array.find((value, index) => {
  
  if (index === 0) {
    console.log('Deleting array[5] with value ', array[5]);
    delete array[5];
  }
  
  console.log('Visited index ', index, ' with value ', value);
});
















Specifications

Browser compatibility

Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox для Android Opera Android Safari на IOS Samsung Internet Deno Node.js
find

45

12

25

No

32

8

45

45

4

32

8

5.0

1.0

4.0.0

0.12.0

See also

  • Полифилл Array.prototype.find в core-js
  • Array.prototype.findIndex() — найти и вернуть индекс
  • Array.prototype.includes() — проверяет, существует ли значение в массиве.
  • Array.prototype.filter() — удалить все несоответствующие элементы
  • Array.prototype.every() — проверить все элементы
  • Array.prototype.some() — тестировать до совпадения одного элемента


JavaScript

  • Array.prototype.fill()

    Метод fill()изменяет все элементы в массиве на статическое значение,начиная с начального индекса (по умолчанию 0)и заканчивая длиной массива (array.length).

  • Array.prototype.filter()

    Метод filter()создает неглубокую копию заданного массива порций,отфильтрованную до элементов,прошедших тест,реализованный предоставленной функцией.

  • Array.prototype.findIndex()

    Метод findIndex()возвращает в качестве первого элемента массив,удовлетворяющий заданной функции тестирования.

  • Array.prototype.findLast()

    Метод findLast()возвращает значение элемента массива,который удовлетворяет заданной функции тестирования.

0 / 0 / 0

Регистрация: 19.09.2011

Сообщений: 78

1

Как найти элемент по его значению в массиве массивов

21.05.2012, 16:21. Показов 2922. Ответов 7


Студворк — интернет-сервис помощи студентам

Подскажите плс как найти элемент по его значению в массиве массивов?(string[][])



0



Эксперт .NET

17173 / 12634 / 3314

Регистрация: 17.09.2011

Сообщений: 20,905

21.05.2012, 16:30

2

Что именно найти нужно?
Просто узнать, имеется ли элемент?
Количество элементов?
Координаты элемента?



0



Dimblch

49 / 49 / 5

Регистрация: 11.07.2011

Сообщений: 282

21.05.2012, 16:45

3

Пробежаться по этому массиву и путем сравнения текущего элемента массива с тем, что ищем, найти его!

Пройтись по массиву -с помощью двух циклов (один вложен в другой)

Пример

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static void search()
        {
            int element = Convert.ToInt32(Console.ReadLine());
            int i_cor, j_cor;
            //массив 3x3 объявление и инициализация.
            int[,] massiv =  {
                               { 1, 2, 3 },
                               { 2, 3, 6 },
                               { 3, 2, 3 }
                             };
 
            for(int i = 0;i<massiv.GetLength(0);i++)
                for (int j = 0; j < massiv.GetLength(1); j++)
                {
                    if (massiv[i, j] == element)
                    {
                        i_cor = i;
                        j_cor = j;
                    }
                }
        }



0



543 / 544 / 181

Регистрация: 16.03.2012

Сообщений: 1,160

Записей в блоге: 2

21.05.2012, 16:49

4

Dimblch то, что написали вы верно для двумерных массивов. А автор спрашивает о массиве массивов, т.е. о ступенчатых массивах, это немного другое. Только вот не особо понятно, что именно надо искать в ступенчатом массиве!



0



49 / 49 / 5

Регистрация: 11.07.2011

Сообщений: 282

21.05.2012, 16:53

5

Да, не заметил..
ну там ведь то же самое будет)
прогон по всем элементам и сравнение.



0



543 / 544 / 181

Регистрация: 16.03.2012

Сообщений: 1,160

Записей в блоге: 2

21.05.2012, 17:00

6

Цитата
Сообщение от Dimblch
Посмотреть сообщение

ну там ведь то же самое будет)

подмассивы могут иметь разные размерности…



0



0 / 0 / 0

Регистрация: 19.09.2011

Сообщений: 78

21.05.2012, 17:00

 [ТС]

7

Цитата
Сообщение от buntar
Посмотреть сообщение

подмассивы могут иметь разные размерности…

я почему то нереально сенни туплю)) уже решил проблему, простите



0



Dimblch

49 / 49 / 5

Регистрация: 11.07.2011

Сообщений: 282

21.05.2012, 17:06

8

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private static void Main()
        {
            int element = Convert.ToInt32(Console.ReadLine());
            int i_cor, j_cor;
 
 
            //массив 3x3 объявление и инициализация.
            int[][] massiv = new int[3][];
            for (int i = 0; i < massiv.Length; i++)
            {
                massiv[i] = new int[3]; //создаем внутренний массив
                for (int j = 0; j < massiv[i].Length; j++)
                    massiv[i][j] = i * 3 + j;
            }
 
 
            for (int i = 0; i < massiv.Length ; i++)
                for (int j = 0; j < massiv[i].Length; j++)
                {
                    if (massiv[i][j] == element)
                    {
                        i_cor = i;
                        j_cor = j;
                    }
                }
        }



0



Добавить комментарий