Как найти номер вхождения элемента массива

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

Например,

Input:

 
nums = [2, 5, 5, 5, 6, 6, 8, 9, 9, 9]
target = 5

 
Output:

 
The first occurrence of element 5 is located at index 1
The last occurrence of element 5 is located at index 3

 
 
Input:

 
nums = [2, 5, 5, 5, 6, 6, 8, 9, 9, 9]
target = 4

 
Output:

 
Element not found in the array

Потренируйтесь в этой проблеме

Простым решением было бы запустить линейный поиск в массиве и вернуть первое или последнее вхождение данного элемента. Проблема с этим подходом заключается в том, что его временная сложность в наихудшем случае равна O(n), куда n это размер ввода. Это решение также не использует тот факт, что ввод отсортирован. Мы можем легко решить эту проблему в O(log(n)) время, изменив алгоритм бинарного поиска.

Поиск первого вхождения элемента

Стандартный бинарный поиск завершается, как только найдено любое вхождение заданного целевого элемента. Чтобы найти первое вхождение данного элемента, измените двоичный поиск, чтобы он продолжал поиск даже при обнаружении целевого элемента. Вместо этого обновите результат до mid и искать влево (в сторону более низких индексов), т. е. модифицировать наше пространство поиска, регулируя высокое значение до mid-1 при нахождении цели в середине индекса.

Ниже приведена программа на C, Java и Python, которая демонстрирует это:

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

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

#include <stdio.h>

// Функция для поиска первого вхождения заданного числа в отсортированном массиве целых чисел

int findFirstOccurrence(int nums[], int n, int target)

{

    // область поиска nums[low…high]

    int low = 0, high = n 1;

    // инициализируем результат на -1

    int result = 1;

    // цикл до тех пор, пока пространство поиска не будет исчерпано

    while (low <= high)

    {

        // находим среднее значение в пространстве поиска и сравниваем его с целевым

        int mid = (low + high)/2;

        // если цель обнаружена, обновить результат и

        // поиск влево (нижние индексы)

        if (target == nums[mid])

        {

            result = mid;

            high = mid 1;

        }

        // если цель меньше среднего элемента, отбрасываем правую половину

        else if (target < nums[mid]) {

            high = mid 1;

        }

        // если цель больше среднего элемента, отбрасываем левую половину

        else {

            low = mid + 1;

        }

    }

    // вернуть самый левый индекс или -1, если элемент не найден

    return result;

}

int main(void)

{

    int nums[] = {2, 5, 5, 5, 6, 6, 8, 9, 9, 9};

    int n = sizeof(nums)/sizeof(nums[0]);

    int target = 5;

    int index = findFirstOccurrence(nums, n, target);

    if (index != 1)

    {

        printf(«The first occurrence of element %d is located at index %d»,

                target, index);

    }

    else {

        printf(«Element not found in the array»);

    }

    return 0;

}

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

результат:

The first occurrence of element 5 is located at index 1

Java

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

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

class Main

{

    // Функция для поиска первого вхождения заданного числа

    // в отсортированном целочисленном массиве

    public static int findFirstOccurrence(int[] nums, int target)

    {

        // область поиска nums[left…right]

        int left = 0;

        int right = nums.length 1;

        // инициализируем результат на -1

        int result = 1;

        // цикл до тех пор, пока пространство поиска не будет исчерпано

        while (left <= right)

        {

            // находим среднее значение в пространстве поиска и сравниваем его с целевым

            int mid = (left + right) / 2;

            // если цель обнаружена, обновить результат и

            // поиск влево (нижние индексы)

            if (target == nums[mid])

            {

                result = mid;

                right = mid 1;

            }

            // если цель меньше среднего элемента, отбрасываем правую половину

            else if (target < nums[mid]) {

                right = mid 1;

            }

            // если цель больше среднего элемента, отбрасываем левую половину

            else {

                left = mid + 1;

            }

        }

        // вернуть самый левый индекс или -1, если элемент не найден

        return result;

    }

    public static void main(String[] args)

    {

        int[] nums = {2, 5, 5, 5, 6, 6, 8, 9, 9, 9};

        int target = 5;

        int index = findFirstOccurrence(nums, target);

        if (index != 1)

        {

            System.out.println(«The first occurrence of element « + target +

                            » is located at index « + index);

        }

        else {

            System.out.println(«Element not found in the array»);

        }

    }

}

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

результат:

The first occurrence of element 5 is located at index 1

Python

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

41

42

43

44

45

46

# Функция поиска первого вхождения заданного числа

# в отсортированном списке целых чисел

def findFirstOccurrence(nums, target):

    # пространство поиска nums[left…right]

    (left, right) = (0, len(nums) 1)

    # инициализирует результат значением -1

    result = 1

    # Цикл # до тех пор, пока пространство поиска не будет исчерпано

    while left <= right:

        # находит среднее значение в пространстве поиска и сравнивает его с целевым

        mid = (left + right) // 2

        #, если цель обнаружена, обновить результат и

        # поиск влево (нижние индексы)

        if target == nums[mid]:

            result = mid

            right = mid 1

        #, если цель меньше среднего элемента, отбросить правую половину

        elif target < nums[mid]:

            right = mid 1

        #, если цель больше среднего элемента, отбросить левую половину

        else:

            left = mid + 1

    # возвращает самый левый индекс или -1, если элемент не найден

    return result

if __name__ == ‘__main__’:

    nums = [2, 5, 5, 5, 6, 6, 8, 9, 9, 9]

    target = 5

    index = findFirstOccurrence(nums, target)

    if index != 1:

        print(f‘The first occurrence of element {target} is located at index {index}’)

    else:

        print(‘Element found not in the list’)

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

результат:

The first occurrence of element 5 is located at index 1

Поиск последнего вхождения элемента

Чтобы найти последнее вхождение элемента, измените стандартный двоичный поиск, чтобы он продолжал поиск даже при обнаружении цели. Вместо этого обновите результат до mid и продолжим поиск вправо (в направлении более высоких индексов), т. е. модифицируем наше пространство поиска, изменив низкие значения на mid+1 при нахождении цели в середине индекса.

Ниже приведена реализация C, Java и Python, основанная на приведенной выше идее:

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

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

#include <stdio.h>

// Функция для поиска последнего вхождения заданного числа в отсортированном массиве целых чисел

int findLastOccurrence(int nums[], int n, int target)

{

    // область поиска nums[low…high]

    int low = 0, high = n 1;

    // инициализируем результат на -1

    int result = 1;

    // цикл до тех пор, пока пространство поиска не будет исчерпано

    while (low <= high)

    {

        // находим среднее значение в пространстве поиска и сравниваем его с целевым

        int mid = (low + high)/2;

        // если цель обнаружена, обновить результат и

        // поиск вправо (более высокие индексы)

        if (target == nums[mid])

        {

            result = mid;

            low = mid + 1;

        }

        // если цель меньше среднего элемента, отбрасываем правую половину

        else if (target < nums[mid]) {

            high = mid 1;

        }

        // если цель больше среднего элемента, отбрасываем левую половину

        else {

            low = mid + 1;

        }

    }

    // вернуть самый левый индекс или -1, если элемент не найден

    return result;

}

int main(void)

{

    int nums[] = {2, 5, 5, 5, 6, 6, 8, 9, 9, 9};

    int n = sizeof(nums)/sizeof(nums[0]);

    int target = 5;

    int index = findLastOccurrence(nums, n, target);

    if (index != 1)

    {

        printf(«The last occurrence of element %d is located at index %d»,

                target, index);

    }

    else {

        printf(«Element not found in the array»);

    }

    return 0;

}

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

результат:

The last occurrence of element 5 is located at index 3

Java

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

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

class Main

{

    // Функция для поиска последнего вхождения заданного числа

    // в отсортированном целочисленном массиве

    public static int findLastOccurrence(int[] nums, int target)

    {

        // область поиска nums[left…right]

        int left = 0;

        int right = nums.length 1;

        // инициализируем результат на -1

        int result = 1;

        // цикл до тех пор, пока пространство поиска не будет исчерпано

        while (left <= right)

        {

            // находим среднее значение в пространстве поиска и сравниваем его с целевым

            int mid = (left + right) / 2;

            // если цель обнаружена, обновить результат и

            // поиск вправо (более высокие индексы)

            if (target == nums[mid])

            {

                result = mid;

                left = mid + 1;

            }

            // если цель меньше среднего элемента, отбрасываем правую половину

            else if (target < nums[mid]) {

                right = mid 1;

            }

            // если цель больше среднего элемента, отбрасываем левую половину

            else {

                left = mid + 1;

            }

        }

        // вернуть самый левый индекс или -1, если элемент не найден

        return result;

    }

    public static void main(String[] args)

    {

        int[] nums = {2, 5, 5, 5, 6, 6, 8, 9, 9, 9};

        int target = 5;

        int index = findLastOccurrence(nums, target);

        if (index != 1)

        {

            System.out.println(«The last occurrence of element « + target +

                    » is located at index « + index);

        }

        else {

            System.out.println(«Element not found in the array»);

        }

    }

}

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

результат:

The last occurrence of element 5 is located at index 3

Python

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

41

42

43

44

45

# Функция поиска последнего вхождения заданного числа в отсортированном списке целых чисел

def findLastOccurrence(nums, target):

    # пространство поиска nums[left…right]

    (left, right) = (0, len(nums) 1)

    # инициализирует результат значением -1

    result = 1

    # Цикл # до тех пор, пока пространство поиска не будет исчерпано

    while left <= right:

        # находит среднее значение в пространстве поиска и сравнивает его с целевым

        mid = (left + right) // 2

        #, если цель обнаружена, обновить результат и

        # поиск вправо (более высокие индексы)

        if target == nums[mid]:

            result = mid

            left = mid + 1

        #, если цель меньше среднего элемента, отбросить правую половину

        elif target < nums[mid]:

            right = mid 1

        #, если цель больше среднего элемента, отбросить левую половину

        else:

            left = mid + 1

    # возвращает самый левый индекс или -1, если элемент не найден

    return result

if __name__ == ‘__main__’:

    nums = [2, 5, 5, 5, 6, 6, 8, 9, 9, 9]

    target = 5

    index = findLastOccurrence(nums, target)

    if index != 1:

        print(f‘The last occurrence of element {target} is located at index {index}’)

    else:

        print(‘Element found not in the list’)

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

результат:

The last occurrence of element 5 is located at index 3

Временная сложность приведенных выше решений равна O(log(n)) и не требует дополнительного места.

 
Упражнение:

1. Напишите рекурсивную версию приведенных выше решений.

2. Проверьте, встречается ли данное целое число больше, чем n/2 раз в отсортированном массиве.

 
Использованная литература:

I am trying to find the indexes of all the instances of an element, say, «Nano», in a JavaScript array.

var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];

I tried jQuery.inArray, or similarly, .indexOf(), but it only gave the index of the last instance of the element, i.e. 5 in this case.

How do I get it for all instances?

Menai Ala Eddine - Aladdin's user avatar

asked Dec 27, 2013 at 9:52

norbdum's user avatar

The .indexOf() method has an optional second parameter that specifies the index to start searching from, so you can call it in a loop to find all instances of a particular value:

function getAllIndexes(arr, val) {
    var indexes = [], i = -1;
    while ((i = arr.indexOf(val, i+1)) != -1){
        indexes.push(i);
    }
    return indexes;
}

var indexes = getAllIndexes(Cars, "Nano");

You don’t really make it clear how you want to use the indexes, so my function returns them as an array (or returns an empty array if the value isn’t found), but you could do something else with the individual index values inside the loop.

UPDATE: As per VisioN’s comment, a simple for loop would get the same job done more efficiently, and it is easier to understand and therefore easier to maintain:

function getAllIndexes(arr, val) {
    var indexes = [], i;
    for(i = 0; i < arr.length; i++)
        if (arr[i] === val)
            indexes.push(i);
    return indexes;
}

answered Dec 27, 2013 at 9:59

nnnnnn's user avatar

nnnnnnnnnnnn

147k30 gold badges199 silver badges239 bronze badges

14

Another alternative solution is to use Array.prototype.reduce():

["Nano","Volvo","BMW","Nano","VW","Nano"].reduce(function(a, e, i) {
    if (e === 'Nano')
        a.push(i);
    return a;
}, []);   // [0, 3, 5]

N.B.: Check the browser compatibility for reduce method and use polyfill if required.

answered Dec 27, 2013 at 10:10

VisioN's user avatar

VisioNVisioN

143k32 gold badges281 silver badges280 bronze badges

7

More simple way with es6 style.

const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);


//Examples:
var cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
indexOfAll(cars, "Nano"); //[0, 3, 5]
indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []

answered Oct 25, 2018 at 8:20

awmidas's user avatar

awmidasawmidas

6435 silver badges13 bronze badges

You can write a simple readable solution to this by using both map and filter:

const nanoIndexes = Cars
  .map((car, i) => car === 'Nano' ? i : -1)
  .filter(index => index !== -1);

EDIT: If you don’t need to support IE/Edge (or are transpiling your code), ES2019 gave us flatMap, which lets you do this in a simple one-liner:

const nanoIndexes = Cars.flatMap((car, i) => car === 'Nano' ? i : []);

answered Mar 2, 2019 at 2:32

Zac Delventhal's user avatar

Zac DelventhalZac Delventhal

3,4732 gold badges20 silver badges26 bronze badges

2

I just want to update with another easy method.

You can also use forEach method.

var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];

var result = [];

Cars.forEach((car, index) => car === 'Nano' ? result.push(index) : null)

answered Feb 12, 2019 at 11:21

JKhan's user avatar

JKhanJKhan

1,1474 gold badges14 silver badges23 bronze badges

Note: MDN gives a method using a while loop:

var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
  indices.push(idx);
  idx = array.indexOf(element, idx + 1);
}

I wouldn’t say it’s any better than other answers. Just interesting.

answered May 16, 2018 at 17:53

abalter's user avatar

abalterabalter

9,52517 gold badges89 silver badges142 bronze badges

const indexes = cars
    .map((car, i) => car === "Nano" ? i : null)
    .filter(i => i !== null)

answered Jun 16, 2019 at 5:54

Michael Pearson's user avatar

Michael PearsonMichael Pearson

5641 gold badge4 silver badges10 bronze badges

3

This worked for me:

let array1 = [5, 12, 8, 130, 44, 12, 45, 12, 56];
let numToFind = 12
let indexesOf12 = [] // the number whose occurrence in the array we want to find

array1.forEach(function(elem, index, array) {
    if (elem === numToFind) {indexesOf12.push(index)}
    return indexesOf12
})

console.log(indexesOf12) // outputs [1, 5, 7]

answered Feb 10, 2019 at 3:05

Jona Dev's user avatar

Just to share another method, you can use Function Generators to achieve the result as well:

function findAllIndexOf(target, needle) {
  return [].concat(...(function*(){
    for (var i = 0; i < target.length; i++) if (target[i] === needle) yield [i];
  })());
}

var target = "hellooooo";
var target2 = ['w','o',1,3,'l','o'];

console.log(findAllIndexOf(target, 'o'));
console.log(findAllIndexOf(target2, 'o'));

answered May 15, 2019 at 9:08

briosheje's user avatar

brioshejebriosheje

7,2962 gold badges32 silver badges53 bronze badges

["a", "b", "a", "b"]
   .map((val, index) => ({ val, index }))
   .filter(({val, index}) => val === "a")
   .map(({val, index}) => index)

=> [0, 2]

answered Nov 21, 2019 at 17:55

Dávid Konkoly's user avatar

Dávid KonkolyDávid Konkoly

1,7251 gold badge12 silver badges8 bronze badges

1

You can use Polyfill

if (!Array.prototype.filterIndex) 
{
    Array.prototype.filterIndex = function (func, thisArg) {

        'use strict';
        if (!((typeof func === 'Function' || typeof func === 'function') && this))
            throw new TypeError();

        let len = this.length >>> 0,
            res = new Array(len), // preallocate array
            t = this, c = 0, i = -1;

        let kValue;
        if (thisArg === undefined) {
            while (++i !== len) {
                // checks to see if the key was set
                if (i in this) {
                    kValue = t[i]; // in case t is changed in callback
                    if (func(t[i], i, t)) {
                        res[c++] = i;
                    }
                }
            }
        }
        else {
            while (++i !== len) {
                // checks to see if the key was set
                if (i in this) {
                    kValue = t[i];
                    if (func.call(thisArg, t[i], i, t)) {
                        res[c++] = i;
                    }
                }
            }
        }

        res.length = c; // shrink down array to proper size
        return res;
    };
}

Use it like this:

[2,23,1,2,3,4,52,2].filterIndex(element => element === 2)

result: [0, 3, 7]

answered May 17, 2020 at 8:19

EbiPenMan's user avatar

We can use Stack and push «i» into the stack every time we encounter the condition «arr[i]==value»

Check this:

static void getindex(int arr[], int value)
{
    Stack<Integer>st= new Stack<Integer>();
    int n= arr.length;
    for(int i=n-1; i>=0 ;i--)
    {
        if(arr[i]==value)
        {
            st.push(i);
        }
    }   
    while(!st.isEmpty())
    {
        System.out.println(st.peek()+" ");
        st.pop(); 
    }
}

answered Mar 27, 2018 at 4:29

S Banzal's user avatar

1

When both parameter passed as array


    function getIndexes(arr, val) {
        var indexes = [], i;
        for(i = 0; i < arr.length; i++){
    for(j =0; j< val.length; j++) {
     if (arr[i] === val[j])
                indexes.push(i);
    }
    }    
        return indexes;
    }

answered Mar 30, 2021 at 10:07

Minhal Kizhakkayil's user avatar

Also, findIndex() will be useful:

var cars = ['Nano', 'Volvo', 'BMW', 'Nano', 'VW', 'Nano'];

const indexes = [];
const searchedItem = 'NaNo';

cars.findIndex((value, index) => {
  if (value.toLowerCase() === searchedItem.toLowerCase()) {
    indexes.push(index);
  }
});

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

Bonus:

This custom solution using Object.entries() and forEach()

var cars = ['Nano', 'Volvo', 'BMW', 'Nano', 'VW', 'Nano'];

const indexes = [];
const searchableItem = 'Nano';

Object.entries(cars).forEach((item, index) => {
  if (item[1].toLowerCase() === searchableItem.toLowerCase())
    indexes.push(index);
});

console.log(indexes);

Note: I did not run run all tests

answered Dec 19, 2022 at 19:52

Menai Ala Eddine - Aladdin's user avatar

findIndex retrieves only the first index which matches callback output. You can implement your own findIndexes by extending Array , then casting your arrays to the new structure .

class EnhancedArray extends Array {
  findIndexes(where) {
    return this.reduce((a, e, i) => (where(e, i) ? a.concat(i) : a), []);
  }
}
   /*----Working with simple data structure (array of numbers) ---*/

//existing array
let myArray = [1, 3, 5, 5, 4, 5];

//cast it :
myArray = new EnhancedArray(...myArray);

//run
console.log(
   myArray.findIndexes((e) => e===5)
)
/*----Working with Array of complex items structure-*/

let arr = [{name: 'Ahmed'}, {name: 'Rami'}, {name: 'Abdennour'}];

arr= new EnhancedArray(...arr);


console.log(
  arr.findIndexes((o) => o.name.startsWith('A'))
)

answered Aug 12, 2017 at 2:32

Abdennour TOUMI's user avatar

Abdennour TOUMIAbdennour TOUMI

85.5k38 gold badges243 silver badges250 bronze badges

Для поиска индекса элемента в массиве можно использовать методы indexOf (для первого вхождения) и lastIndexOf (для последнего вхождения).

А как можно найти индекс в массиве объектов? Например индекс при первом вхождении нужного объекта?

Например есть массив объектов:

let inputArr = [{name:'bruce', age:40, city:'gotham'},
                {name:'barry', age:25, city:'fallville'},
                {name:'diana', age:30, city:'themyscira'}
               ];

Как получить индекс, где в свойстве name значение barry? Если писать так:

inputArr.indexOf('barry');

то выведет -1, а ожидаемое значение — 1. Может циклом перебирать все значения? Может есть простые способы?


orig post https://stackoverflow.com/q/8668174/6104996

В статье рассказывается о том, как использовать методы JavaScript indexOf и lastIndexOf для определения расположения элемента внутри массива.

  • Поиск элемента в массиве — знакомство с методом indexOf
  • Примеры применения метода indexOf()
  • Поиск элемента в массиве — знакомство с методом lastIndexOf()
  • Поиск элемента в массиве — примеры использования метода lastIndexOf()

Чтобы определить расположение элемента в массиве, можно воспользоваться методом indexOf(). Он возвращает индекс первого вхождения элемента, либо -1, если он не найден.

Ниже приведен синтаксис метода indexOf():

Array.indexOf(searchElement, fromIndex)

Метод indexOf() принимает два аргумента. searchElement -это элемент, который нужно найти в массиве. fromIndex – это индекс массива, с которого нужно начать поиск.

Аргумент fromIndex в качестве значения может принимать как положительное, так и отрицательное целое число. Если значение аргумента fromIndex будет отрицательным, метод indexOf() начнет поиск по всему массиву плюс значение fromIndex. Если опустить аргумент fromIndex, то метод начнет поиск с элемента 0.

Учтите, что метод JavaScript array indexOf() при сравнении searchElement с элементами в массиве, использует алгоритм строгого равенства, схожий с оператором “тройное равно(===).

Предположим, что есть массив scores, в котором содержится шесть чисел:

var scores = [10, 20, 30, 10, 40, 20];

В следующем примере метод indexOf() используется для поиска элементов в массиве scores:

console.log(scores.indexOf(10)); // 0
console.log(scores.indexOf(30)); // 2
console.log(scores.indexOf(50)); // -1
console.log(scores.indexOf(20)); // 1

Примеры применения метода indexOf()

В примере используется fromIndex с отрицательными значениями:

console.log(scores.indexOf(20,-1)); // 5 (fromIndex = 6+ (-1) = 5)
console.log(scores.indexOf(20,-5)); // 1 (fromIndex = 6+ (-5) = 1)

Предположим, что есть массив объектов. У каждого из них два свойства: name и age:

var guests = [
    {name: 'John Doe', age: 30},
    {name: 'Lily Bush', age: 20},
    {name: 'William Gate', age: 25}
];

Следующие выражение возвращает -1, даже если у первого элемента массива guests и searchElement будут одинаковые значения свойств name и age. Так как это два разных объекта:

console.log(guests.indexOf({
    name: 'John Doe',
    age: 30
})); // -1

Иногда нужно находить индексы всех упоминаний элемента в массиве. В приведенном ниже примере для этого в функции find() используется метод массива JavaScript indexOf():

function find(needle, haystack) {
    var results = [];
    var idx = haystack.indexOf(needle);
    while (idx != -1) {
        results.push(idx);
        idx = haystack.indexOf(needle, idx + 1);
    }
    return results;
}

В следующем примере функция find() используется для возврата массива с позициями числа 10 в массиве scores:

console.log(find(10,scores)); // [0, 3]
JavaScript array lastIndexOf method

У массивов есть еще один метод — lastIndexOf(), который предлагает почти тот же функционал, что и indexOf().

Синтаксис метода lastIndexOf():

Array.lastIndexOf(searchElement[, fromIndex = Array.length – 1])

Метод возвращает индекс последнего вхождения searchElement в массиве. Если элемент не найден, будет возвращено значение -1.

В отличие от метода JavaScript indexOf(), lastIndexOf() сканирует массив в обратном направлении, начиная от значения fromIndex.

Представленное ниже выражение возвращает последние индексы чисел 10 и 20 в массиве scores:

console.log(scores.lastIndexOf(10));// 3
console.log(scores.lastIndexOf(20));// 5

Так как число 50 не находится в массиве, следующее выражение вернет -1.

console.log(scores.lastIndexOf(50));// -1

Мы научились использовать методы JavaScript indexOf() string и lastIndexOf() для поиска элементов в массиве.

Содержание

  • 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}

Заключение

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

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

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