2016-09-06 7 views
1

Мне нужно найти первое дублирующее значение в массиве, а затем вернуть его индекс в переменной firstIndex. Это необходимо сделать для цикла, который должен остановиться после того, как нашел первый дубликат. Я знаю, что это, наверное, довольно просто, но я застрял. До сих пор у меня есть это, но не кажется, что это будет работать:Javascript: Как найти первое дублирующее значение и вернуть его индекс?

var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3]; 
var firstIndex = ""; 
for (var a = 0; a < numbers4.length; a++) { 
    for (var b = a+1; b < numbers4.length; b++) { 
     if (numbers4[a] === numbers4[b]) 
      firstIndex = numbers4.indexOf(numbers4[a]); 
      break; 
    } 
} 
console.log(firstIndex); 

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

Заранее благодарен!

+0

'index' чего? – Rayon

+0

возможно дубликат? http://stackoverflow.com/questions/840781/easiest-way-to-find-duplicate-values-in-a-javascript-array –

+0

@ Джанна Ваша логика правильная, вы пропустили фигурные скобки, проверьте мой ответ –

ответ

2

Изменить код со следующим

var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3]; 
    var firstIndex = ""; 
    var isMatch=false; 
    for (var a = 0; a < numbers4.length; a++) { 
     for (var b = a+1; b < numbers4.length; b++) { 
      if (numbers4[a] === numbers4[b]){ 
       firstIndex = numbers4.indexOf(numbers4[a]); 
       isMatch=true; 
       break; 
      } 
     } 
      if (isMatch) {break;} 
    } 
    console.log(firstIndex); 
+1

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

+0

@SachinNayak спасибо за предложение, я обновил свой ответ. – Amy

+0

Спасибо! Я использовал этот, и он работал – Joanna

1

Я хотел бы использовать объект запоминанием значения уже нашли ... Нечто подобное должно работать;)

var numbers4 = [5, 2, 3, 4, 4, 6, 7, 1, 2, 3]; 
 

 
function findFirstDuplicateIndex(arr){ 
 
    var found = {}; 
 
    
 
    for (var a = 0, aa = arr.length; a < aa ; a++) { 
 
    if (found[arr[a]]) 
 
     return found[arr[a]]; 
 
    
 
    found[numbers4[a]] = a 
 
    } 
 
} 
 

 
console.log(findFirstDuplicateIndex(numbers4));

Это довольно быстро, потому что вы просто зацикливаете один раз через массив. Остальное время вы просто получить доступ к свойству объекта или установить свойство объекта ... Позвольте мне знать, если у вас есть вопросы;)

Однако, возможно, что-то быстрее ... Это просто идея ^^

PS: Он также работает со словами, а не только цифрами

+0

Вы снипплет возвращает '3', в то время как первый дубликат имеет индекс' 4' на самом деле. –

+0

Я думаю, он хочет индекс первого появления дублированного числа ... Он сказал: «Консоль выдает 1, что отлично, потому что 2 - это первый дубликат». Если ему нужен дублированный индекс числа, ему просто нужно вернуть вместо него [arr [a]] –

+0

Умм .. кажется, что вы правы. В любом случае вам не нужно хранить 'found', поскольку вы можете просто использовать' indexOf' или даже 'lastIndexOf', как я это сделал в своем ответе. –

0

Вам даже не нужны вложенные для петель.

var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3]; 
 
var firstIndex = ""; 
 
for (var a = 1; a < numbers4.length; a++) { //start from second elem since first is never a duplicate 
 
     if (numbers4.lastIndexOf(numbers4[a])> a) { 
 
      firstIndex = a; 
 
      break; 
 
     } 
 
} 
 
console.log(firstIndex); //1

Все, что вам нужно сделать во время итерация, чтобы проверить, если текущее значение существует где-то дальше в массиве. Это делается путем проверки последнего индекса этого значения с использованием lastIndexOf().

+0

это по-прежнему эквивалентен O (n^2) –

0

Ваша проблема - у вас есть две петли и только один break, вам нужно вырваться из обоих.

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

var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3]; 
function getDuplicate(numbers4) 
{ 
    for (var a = 0; a < numbers4.length; a++) { 
     for (var b = a+1; b < numbers4.length; b++) { 
      if (numbers4[a] === numbers4[b]){ 
       return a; 
      } 
     } 
    } 
} 
console.log(getDuplicate(numbers4)); 

Однако, вы можете оптимизировать свой код дальше, держа карту

function getDuplicate(numbers) 
{ 
    var map = {}; 
    for (var a = 0; a < numbers.length; a++) 
    { 
     if(map[ numbers[ a ] ]) 
     { 
      return a; 
     } 
     map[ numbers[ a ] ] = true; 
    } 
    return -1; 
} 
0

Вы можете проверить, если indexOf() не равна lastIndexOf() и возвращать значение и разорвать петлю

var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3]; 
 
var firstIndex = ""; 
 
for (var i = 0; i < numbers4.length; i++) { 
 
    if (numbers4.indexOf(numbers4[i]) != numbers4.lastIndexOf(numbers4[i])) { 
 
    firstIndex = i; 
 
    break; 
 
    } 
 
} 
 

 
console.log(firstIndex)

+0

Поскольку текущий индекс является первым для этого значения (потому что вы бы раньше разорвали цикл раньше), здесь здесь 'indexOf' здесь не требуется. Это можно сделать просто с помощью 'i

+0

Это выглядит проще, чем у меня, я проверил, и он работает правильно. Благодаря! – Joanna

0

Ваш перерыв; завершает цикл b, потому что if() не использует скобки {}.

Кроме того, firstIndex должен быть просто установлен как a, так и b в зависимости от того, нужно ли возвращать первое появление дубликата или первое повторение.

Оно должно быть:

if (numbers4[a] === numbers4[b]) 
{ 
      firstIndex = a; 
      break; 
} 
1

Если я правильно понимаю ваш вопрос, это должно помочь вам ... В принципе, вам нужно для двойной итерации.

function firstDupeIndex(primitives) { 
 
    return primitives 
 
    .reduce(function(foundIndex, value, valueIndex) { 
 
     if(foundIndex > -1) { 
 
     return foundIndex; 
 
     } 
 
    
 
     var listWithoutCurrent = primitives 
 
     .filter(function(v, i) { return i !== valueIndex; }) 
 
     ; 
 
    
 
     var matchIndex = listWithoutCurrent.indexOf(value); 
 
     if(matchIndex > -1) { 
 
     foundIndex = matchIndex + 1; 
 
     console.log(value, "found at index", foundIndex); 
 
     } 
 
    
 
     return foundIndex; 
 
    }, -1); 
 
    ; 
 
} 
 

 
console.log(
 
    "First Dupe at index:", 
 
    firstDupeIndex([5, 2, 3, 4, 4, 6, 7, 1, 2, 3]) 
 
);

0

var numbers = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3]; 
 
var firstIndex; 
 
var len = numbers.length; 
 

 
for (var i = 0; i < len; i++) { 
 
    var tmpArray = numbers.slice(i + 1, len); 
 
    var index = tmpArray.indexOf(numbers[i]); 
 
    if (index !== -1) { 
 
    firstIndex = index + i + 1; 
 
    break; 
 
    } 
 
} 
 
console.log(firstIndex);

Update:

На самом деле логика верна, но вы пропустили брекеты if condition, а также если удовлетворяет условию, то его теа нс firstIndex такая же, как a

Это ваш код с фигурными скобками,

var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3]; 
 
var firstIndex = ""; 
 
for (var a = 0; a < numbers4.length; a++) { 
 
    for (var b = a + 1; b < numbers4.length; b++) { 
 
    if (numbers4[a] === numbers4[b]) { 
 
     firstIndex = a 
 
     break; 
 
    } 
 
    } 
 
} 
 
console.log(firstIndex);

+0

lastIndexOf лучше, чем нарезать массив –

Смежные вопросы