Как найти конкретное значение в массиве

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

array_searchОсуществляет поиск данного значения в массиве и возвращает
ключ первого найденного элемента в случае успешного выполнения

Описание

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

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

needle

Искомое значение.

Замечание:

Если needle является строкой, сравнение
происходит с учётом регистра.

haystack

Массив.

strict

Если третий параметр strict установлен в
true, то функция array_search() будет искать
идентичные элементы в haystack.
Это означает, что также будут проверяться
типы
needle в haystack,
а объекты должны быть одним и тем же экземпляром.

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

Возвращает ключ для needle, если он был
найден в массиве, иначе false.

Если needle присутствует в
haystack более одного раза, будет возвращён
первый найденный ключ. Для того, чтобы возвратить ключи для всех
найденных значений, используйте функцию array_keys()
с необязательным параметром search_value.

Внимание

Эта функция может возвращать как логическое значение false, так и значение не типа boolean, которое приводится к false. За более подробной информацией обратитесь к разделу Булев тип. Используйте оператор === для проверки значения, возвращаемого этой функцией.

Примеры

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


<?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;
?>

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

  • array_keys() — Возвращает все или некоторое подмножество ключей массива
  • array_values() — Выбирает все значения массива
  • array_key_exists() — Проверяет, присутствует ли в массиве указанный ключ или индекс
  • in_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'));
?>


  • Главная

  • Инструкции

  • JavaScript

  • Методы поиска в массивах JavaScript

Blog

Поиск в массиве — довольно несложная задача для программиста. На ум сразу приходит перебор через цикл for или бинарный поиск в отсортированном массиве, для элементов которого определены операции «больше» и «меньше». Но, как и любой высокоуровневый язык программирования, JavaScript предлагает разработчику встроенные функции для решения различных задач. В этой статье мы рассмотрим четыре метода поиска в массивах JavaScript: find, includes, indexOf и filter.

Методы Поиска В Массивах Java Script (1)

indexOf

indexOf — это функция поиска элемента в массиве. Этот метод с помощью перебора ищет искомый объект и возвращает его индекс или «-1», если не находит подходящий.

Синтаксис

Функция имеет такой синтаксис:

Array.indexOf (search element, starting index)

где:

  • Array — массив;
  • search element — элемент, который мы ищем;
  • starting index — индекс, с которого начинаем перебор. Необязательный аргумент, по умолчанию работа функции начинается с индекса “0”, т.е. метод проверяет весь Array. Если starting index больше или равен Array.length, то метод сразу возвращает “-1” и завершает работу. 

Если starting index отрицательный, то JS трактует это как смещение с конца  массива: при starting index = “-1” будет проверен только последний элемент, при “-2” последние два и т.д. 

Практика

Опробуем метод на практике. Запустим такой код и проверим результаты его работы:

let ExampleArray = [1,2,3,1,'5', null, false, NaN,3];

console.log("Позиция единицы", ExampleArray.indexOf(1) );
console.log("Позиция следующей единицы", ExampleArray.indexOf(1,2) );
console.log("Позиция тройки", ExampleArray.indexOf(3) );
console.log("Позиция тройки, если starting index отрицательный", ExampleArray.indexOf(3,-2) );
console.log("Позиция false", ExampleArray.indexOf(false) );
console.log("Позиция 5", ExampleArray.indexOf("5") ); 
console.log("Позиция NaN", ExampleArray.indexOf(NaN));

В результате работы этого кода мы получили такой вывод: 

Позиция единицы 0
Позиция следующей единицы 3
Позиция тройки 2
Позиция тройки, если starting index отрицательный 8
Позиция false 6
Позиция 5 -1
Позиция NaN -1

indexOf осуществляет поиск элемента в массиве слева направо и останавливает свою работу на первом совпавшем. Отчетливо это проявляется в примере с единицей. Для того, чтобы идти справа налево, используйте метод LastIndexOf с аналогичным синтаксисом.

Для сравнения искомого и очередного объекта применяется строгое сравнение (===). При использовании строгого сравнения для разных типов данных, но с одинаковым значение, например 5, ‘5’ и “5” JavaScript даёт отрицательный результат, поэтому IndexOf не нашел 5. 

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

includes

includes не совсем проводит поиск заданного элемента в массиве, а проверяет, есть ли он там вообще. Работает он примерно также как и indexOf. В конце работы includes возвращает «True», если нашел искомый объект, и «False», если нет. Также includes правильно обрабатывает NaN

Синтаксис

includes имеет следующий синтаксис:

Array.includes (search element, starting index)

где: 

  • Array — массив;
  • search element — элемент, который мы ищем;
  • starting index — индекс, с которого начинаем перебор. Необязательный аргумент, по умолчанию работа функции начинается с индекса “0”, т.е. метод проверяет весь Array. Если starting index больше или равен Array.length, то метод сразу возвращает «False» и завершает работу.  

Если starting index отрицательный, то JS трактует это как смещение с конца массива: при starting index = “-1” будет проверен только последний элемент, при “-2” последние два и т.д.  

Практика

Немного изменим код из предыдущего примера и запустим его:

let Example = [1,2,3,1,'5', null, false,NaN, 3];

console.log("Наличие единицы", Example.includes(1) );
console.log("Наличие следующей единицы", Example.includes(1,2) );
console.log("Наличие тройки", Example.includes(3) );
console.log("Наличие тройки, если starting index отрицательный", Example.includes(3,-1) );
console.log("Наличие false", Example.includes(false) );
console.log("Наличие 5", Example.includes(5) ); 
console.log("Наличие NaN", Example.includes(NaN));

Вывод:

Наличие единицы true
Наличие следующей единицы true
Наличие тройки true
Наличие тройки, если starting index отрицательный true
Наличие false true
Наличие 5 false
Наличие NaN true

Для includes отсутствует альтернативная функция, которая проводит поиск по массиву js справа налево, которая, в общем-то, и не очень актуальна.

find

Предположим, что нам нужно найти в массиве некий объект. Но мы хотим найти его не по значению, а по его свойству. Например, поиск числа в массиве со значением между 15 и 20. Как и прежде, мы можем воспользоваться перебором с помощью for, но это не слишком удобно. Для поиска с определенным условием в JavaScript существует метод find.

Синтаксис

Array.find(function(...){
//если элемент соответствует условиям (true), то функция возвращает его  и прекращает работу;
//если ничего не найдено, то возвращает undefined
})
  • Array — массив;
  • function(…) — функция, которая задает условия.

Практика

Как и в прошлых примерах, напишем небольшой код и опробуем метод:

let ExampleArray = ["Timeweb", 55555, "Cloud", "облачный провайдер", "буквы"];

console.log(ExampleArray.find(element => element.length == 5))

Вывод:

Cloud

В этом примере мы искали строки с длиной в 5 символов. Для числовых типов данных длина не определена, поэтому 55555 не подходит. find находит первый элемент и возвращает его, поэтому «буквы» также не попали в результат работы нашей функции. Для того, чтобы найти несколько элементов, соответствующих некоторому условию, нужно использовать метод filter.

Также не стоит забывать о методе findIndex. Он возвращает индекс подходящего элемента. Или -1, если его нет. В остальном он работает точно также, как и find.

filter

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

Синтаксис

Array.find(function(...){
//если элемент соответствует условиям (true), то добавляем его к конечному результату и продолжаем перебор;
})
  • Array — массив;
  • function(…) — функция, которая задает условия.

Практика

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

let ExampleArray = [
  [10, 15, 8],
  [11, 12, 6],
  [5, 20, 1],
  [10, 10, 2],
  [16,2, 4]
  ];

console.log(ExampleArray.filter(element=> element[0]*element[1]*element[2]>300))

 Вывод:

[ [ 10, 15, 8 ],
 [ 11, 12, 6 ] ]

В этом примере мы нашли прямоугольные параллелепипеды с объемом больше 300. В целом, метод filter в JS позволяет реализовывать всевозможные условия для поиска. 

Заключение

В этой статье узнали о методах поиска в JavaScript и научились ими пользоваться. Все перечисленные методы — универсальные инструменты для разработчиков. Но, как и любые универсальные инструменты, они не всегда являются самыми производительными. Так, например, бинарный поиск будет куда эффективнее, чем find и filter.

У меня есть массив объектов. Их достаточно большое количество.
Объекты вида:

  {
     id: 123,
     name: 'г. Москва"
  }

Как мне быстро найти среди них объект (он гарантировано будет один), свойство name которого совпадает с моим указанным (например, «г. Москва») и взять его id? Нужен самый оптимальный и быстрый способ.

br3t's user avatar

br3t

4,3794 золотых знака16 серебряных знаков29 бронзовых знаков

задан 13 июл 2017 в 19:53

x137's user avatar

Как оказалось, не все помнят про существование в ES6 метода find. :)

let cities = [{ id: 121, name: 'г. Урюпинск' }, { id: 122, name: 'г. Париж' }, { id: 123, name: 'г. Москва' }, { id: 124, name: 'г. Штормград' }];
let searchTerm = 'г. Москва';
let cityId = cities.find(city => city.name === searchTerm).id
console.log(cityId);

ответ дан 13 июл 2017 в 20:45

Yaant's user avatar

YaantYaant

4,4031 золотой знак16 серебряных знаков24 бронзовых знака

Самым быстрым способом будет создание объекта с ключами-name и доставать просто по ключу.

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

Но самым простым и читаемым вариантом(но более медленным по сравнению с предыдущими) будет filter. Он быстрее перебора массива с помощью for...in/for...of.

ответ дан 13 июл 2017 в 20:06

Sapphiron's user avatar

SapphironSapphiron

9155 серебряных знаков12 бронзовых знаков

Если ECMAScript — то через Array.filter:

var data = [{ id: 123, name: "г. Москва" }, { id: 124, name: "г. Немосква" }];
var cutySearch = "г. Москва";

var cityId = data.filter(function(val) {
  return val.name == cutySearch;
})[0].id;
console.log(cityId);

Либо вручную перебирать:

var data = [{ id: 123, name: "г. Москва" }, { id: 124, name: "г. Немосква" }];
var cutySearch = "г. Москва";

var cityId;
for(var i = 0; i < data.length; i++) {
  if(data[i].name == cutySearch) {
    cityId = data[i].id;
    break;
  }
}
console.log(cityId);

ответ дан 13 июл 2017 в 20:02

br3t's user avatar

br3tbr3t

4,3794 золотых знака16 серебряных знаков29 бронзовых знаков

6

В этом посте будет обсуждаться, как проверить наличие заданного элемента в массиве в C#. Решение должно возвращать true, если массив содержит указанное значение; в противном случае ложно.

1. Использование Enumerable.Contains() метод (System.Linq)

The Enumerable.Contains() предоставляет простой и понятный способ определить, содержит ли последовательность указанный элемент или нет. Следующий пример демонстрирует использование Contains() метод:

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

27

28

29

30

using System;

using System.Linq;

public static class Extensions

{

    public static bool find<T>(this T[] array, T target) {

        return array.Contains(target);

    }

}

public class Example

{

    public static void Main()

    {

        int[] array = { 1, 2, 3, 4, 5 };

        int target = 4;

        bool isExist = array.find(target);

        if (isExist) {

            Console.WriteLine(«Element found in the array»);

        }

        else {

            Console.WriteLine(«Element not found in the given array»);

        }

    }

}

/*

    результат: Element found in the array

*/

Скачать  Выполнить код

2. Использование Array.Exists() метод

The Array.Exists() рекомендуемым решением является проверка существования элемента в массиве. В следующем примере кода показано, как это реализовать.

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

27

28

29

using System;

public static class Extensions

{

    public static bool find<T>(this T[] array, T target) {

        return Array.Exists(array, x => x.Equals(target));

    }

}

public class Example

{

    public static void Main()

    {

        int[] array = { 1, 2, 3, 4, 5 };

        int target = 4;

        bool isExist = array.find(target);

        if (isExist) {

            Console.WriteLine(«Element found in the array»);

        }

        else {

            Console.WriteLine(«Element not found in the given array»);

        }

    }

}

/*

    результат: Element found in the array

*/

Скачать  Выполнить код

3. Использование Array.IndexOf() метод

Другим хорошим решением является использование Array.IndexOf() метод, который возвращает индекс первого вхождения указанного элемента в этот массив и -1 если такого элемента нет.

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

27

28

29

using System;

public static class Extensions

{

    public static bool find<T>(this T[] array, T target) {

        return Array.IndexOf(array, target) != 1;

    }

}

public class Example

{

    public static void Main()

    {

        int[] array = { 1, 2, 3, 4, 5 };

        int target = 4;

        bool isExist = array.find(target);

        if (isExist) {

            Console.WriteLine(«Element found in the array»);

        }

        else {

            Console.WriteLine(«Element not found in the given array»);

        }

    }

}

/*

    результат: Element found in the array

*/

Скачать  Выполнить код

4. Использование Array.FindIndex() метод

Array.FindIndex() возвращает индекс первого элемента, удовлетворяющего предоставленному предикату. Если ни один элемент не удовлетворяет условию, FindIndex возвращается -1.

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

27

28

29

using System;

public static class Extensions

{

    public static bool find<T>(this T[] array, T target) {

        return Array.FindIndex(array, x => x.Equals(target)) != 1;

    }

}

public class Example

{

    public static void Main()

    {

        int[] array = { 1, 2, 3, 4, 5 };

        int target = 4;

        bool isExist = array.find(target);

        if (isExist) {

            Console.WriteLine(«Element found in the array»);

        }

        else {

            Console.WriteLine(«Element not found in the given array»);

        }

    }

}

/*

    результат: Element found in the array

*/

Скачать  Выполнить код

5. Использование HashSet

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

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

27

28

29

30

using System;

using System.Collections.Generic;

public static class Extensions

{

    public static bool find<T>(this T[] array, T target) {

        return new HashSet<T>(array).Contains(target);

    }

}

public class Example

{

    public static void Main()

    {

        int[] array = { 1, 2, 3, 4, 5 };

        int target = 4;

        bool isExist = array.find(target);

        if (isExist) {

            Console.WriteLine(«Element found in the array»);

        }

        else {

            Console.WriteLine(«Element not found in the given array»);

        }

    }

}

/*

    результат: Element found in the array

*/

Скачать  Выполнить код

6. Использование Enumerable.Where() метод (System.Linq)

The System.Linq.Enumerable.Where() Метод фильтрует последовательность значений на основе предиката. В следующем примере кода показано, как мы можем использовать Where() чтобы найти первое вхождение указанного элемента в этом массиве.

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

27

28

29

30

31

32

33

34

35

36

37

38

39

40

using System;

using System.Linq;

public static class Extensions

{

    public static bool find<T>(this T[] array, T target)

    {

        try {

            array.Where(i => i.Equals(target)).First();

            // или же

            // array.First(i => i.Equals(target));

            return true;

        }

        catch (InvalidOperationException) {

            return false;

        }

    }

}

public class Example

{

    public static void Main()

    {

        int[] array = { 1, 2, 3, 4, 5 };

        int target = 4;

        bool isExist = array.find(target);

        if (isExist) {

            Console.WriteLine(«Element found in the array»);

        }

        else {

            Console.WriteLine(«Element not found in the given array»);

        }

    }

}

/*

    результат: Element found in the array

*/

Скачать  Выполнить код

 
Мы можем избежать блока try-catch, установив значение по умолчанию с помощью DefaultIfEmpty() метод:

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

27

28

29

30

31

32

33

using System;

using System.Linq;

public static class Extensions

{

    public static bool find(this int[] array, int target)

    {

        return (array.Where(i => i.Equals(target))

                    .DefaultIfEmpty(1)

                    .First()) != 1;

    }

}

public class Example

{

    public static void Main()

    {

        int[] array = { 1, 2, 3, 4, 5 };

        int target = 4;

        bool isExist = array.find(target);

        if (isExist) {

            Console.WriteLine(«Element found in the array»);

        }

        else {

            Console.WriteLine(«Element not found in the given array»);

        }

    }

}

/*

    результат: Element found in the array

*/

Скачать  Выполнить код

7. Использование Array.FindAll() метод

Array.FindAll() Метод возвращает массив, содержащий все элементы, соответствующие указанному предикату. Мы можем использовать его следующим образом, чтобы проверить наличие элемента в массиве.

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

27

28

29

30

31

using System;

public static class Extensions

{

    public static bool find<T>(this T[] array, T target)

    {

        T[] results = Array.FindAll(array, x => x.Equals(target));

        return results.Length > 0;

    }

}

public class Example

{

    public static void Main()

    {

        int[] array = { 1, 2, 3, 4, 5 };

        int target = 4;

        bool isExist = array.find(target);

        if (isExist) {

            Console.WriteLine(«Element found in the array»);

        }

        else {

            Console.WriteLine(«Element not found in the given array»);

        }

    }

}

/*

    результат: Element found in the array

*/

Скачать  Выполнить код

8. Выполнение линейного поиска

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

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

27

28

29

30

31

32

33

34

35

36

37

38

39

using System;

using System.Collections.Generic;

public static class Extensions

{

    public static bool find<T>(this T[] array, T target)

    {

        EqualityComparer<T> comparer = EqualityComparer<T>.Default;

        for (int i = 0; i < array.Length; i++)

        {

            if (comparer.Equals(array[i], target)) {

                return true;

            }

        }

        return false;

    }

}

public class Example

{

    public static void Main()

    {

        int[] array = { 1, 2, 3, 4, 5 };

        int target = 4;

        bool isExist = array.find(target);

        if (isExist) {

            Console.WriteLine(«Element found in the array»);

        }

        else {

            Console.WriteLine(«Element not found in the given array»);

        }

    }

}

/*

    результат: Element found in the array

*/

Скачать  Выполнить код

Это все о поиске элемента в массиве в C#.

Перевод статьи 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!

Понравилась статья? Поделить с друзьями:
  • Как найти фото на айфоне которые удалили
  • Как найти значение емкости конденсатора в цепи
  • Как составить конкуренцию магазину
  • Как составить предложения на английском языке в future simple
  • Как найти прохождение техосмотра