Как мне найти все индексы малого значения массива, если наименьшее значение появляется несколько раз?

#javascript

#javascript

Вопрос:

Как и в вопросе, я хочу найти все значения Math.min (точнее, их индексы). Если мой вопрос недостаточно ясен, возможно, этот пример поможет:

Допустим, у меня есть массив [1, 31, 15, 1, 7, 1]. Я хочу найти индексы малого значения в этом массиве, которое равно 1 — поэтому программа должна вернуть [0, 3, 5] . Вот небольшая программа, которую я написал:

 let arr = [1, 31, 15, 1, 7, 1];
let newArr = [];
for (let a = 0; a < arr.length; a  ) {
    newArr[a] = arr.indexOf(Math.min(...arr));
    arr.splice(a, 1);
}

console.log(newArr); 

Тем не менее, результат равен [0, 2, 1], и я не понимаю, почему. Если бы кто-нибудь мог указать мне правильное направление или помочь мне понять, почему это не работает, я был бы чрезвычайно счастлив! Заранее спасибо!

Комментарии:

1. у вас всегда есть положительные целые числа меньше 2 ^ 32-1?

2. Да, целые числа будут максимальными на уровне 1000.

Ответ №1:

Это одно из наиболее оптимальных решений с O (n),

 let arr = [1, 31, 15, 1, 7, 1];
let newArr = [];
let minimum = Infinity;
for (let a = 0; a < arr.length; a  ) {
    if(arr[a] === minimum) { 
       newArr.push(a);
    } else if(arr[a] < minimum) {
       newArr = [a];
       minimum = arr[a];
    } 
}

console.log(newArr); 

Ответ №2:

Оптимальное решение

 const arr = [1, 31, 15, 1, 7, 1];
const indexes = arr.reduce(([indxs, minValue], v, ind) => {
  if (v > minValue) return [indxs, minValue]
  if (v < minValue) indxs = []
  indxs.push(ind)
  return [indxs, v]
}, [[], Infinity])[0] 

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

Комментарии:

1. хм, попробуйте использовать 1000 вместо 1 и имейте в виду: » … если наименьшее значение появляется несколько раз «.

Ответ №3:

Ваш подход изменяет массив с splice помощью . Это изменяет индексы и делает данный массив недействительным по индексу.

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

Подход с одним циклом:

 let array = [100, 31, 15, 100, 7, 100],
    indices = {},
    smallest = Number.MAX_VALUE;

for (let index = 0; index < array.length; index  ) {
    const value = array[index];
    if (value > smallest) continue;

    if (!indices[value]) indices[value] = [];
    if (indices[value].push(index) === 2 amp;amp; value < smallest) smallest = value;
}

console.log(indices[smallest]); 

Комментарии:

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

2. лучше, но индексы по-прежнему не нужны, нужен просто результирующий массив, если следующее значение меньше наименьшего, сделайте length = 0 или переназначите пустой массив, и все

3. нет, вам нужно сохранить другие значения, а затем взять наименьшее, по крайней мере, с двумя индексами.

4. Ха-ха, я не думаю, что это так, в противном случае, конечно, вы правы