3
votes

Index Ruby des éléments du tableau

Considérez que j'ai un tableau d'éléments entiers. Dans lequel j'essaye de trouver l'index où commence une longue séquence de nombres répétitifs.

my_array.each with_index do |e, x|
  match = e.to_s * 5
  next_10 = my_array[x + 1, 5].join()

  if match == next_10
    puts "index #{x}"
    break
  end
end

#index 14

Ci-dessous est la façon dont j'essaye de trouver l'index. Quelqu'un peut-il me suggérer une manière plus optimisée et correcte de le faire?

my_array = [100, 101, 100, 102, 100, 100, 101, 100, 250, 251, 253, 260, 250, 200, 100, 100, 100, 100, 100, 100, 100, 100, 100, 120]


7 commentaires

Quelle est votre définition de la normalisation du tableau?


@ray mêmes éléments commencent à apparaître.


@Aparichith "les mêmes éléments commencent à apparaître" est un peu vague. Cela ressemble presque à "vous le saurez quand vous le verrez". Soyez plus précis, s'il vous plaît.


@Stefan Nous pouvons définir une fonction pour trouver l'index de départ de la plus longue séquence de nombres répétitifs mais cela ne le définit pas normalisé.


"Quelqu'un peut-il me suggérer [une] méthode plus [...] correcte" - quel est le problème avec votre approche?


J'ai mis à jour la question.


Voulez-vous trouver l'index du premier élément de la plus longue séquence d'éléments égaux? Si tel est le cas, cela doit être précisé. Nulle part vous ne dites que vous recherchez la séquence la plus longue ayant une certaine propriété. N'hésitez pas à utiliser le contenu de ma première phrase dans une édition, si j'ai raison.


4 Réponses :


2
votes
my_array.index.with_index{|value,index| my_array[index,6].uniq.size==1}
This is a kind of tweak, if you mean "optimised" just in the way code looks like.If you mean optimised performance. it does not fit.

2 commentaires

pouvez-vous expliquer comment le numéro 6 fonctionne ici? semble que cela ne fonctionnera pas pour d'autres combinaisons d'entiers.


La question a été modifiée. Cette réponse est basée sur le code de démonstration.



1
votes

Dans la première itération, j'obtiens un tableau de séquence d'éléments répétitifs, puis je continue avec la logique,

groups = my_array[1..-1].inject([[my_array[0]]]) { |m, n| m.last[0] == n ? m.last << n : m << [n]; m }
# => [[100], [101], [100], [102], [100, 100], [101], [100], [250], [251], [253], [260], [250], [200], [100, 100, 100, 100, 100, 100, 100, 100, 100], [120]]

groups[0,groups.index(groups.sort { |a,b| a.count <=> b.count }.last)].flatten.count
# => 14

En utilisant regex, cela peut être précis et simple.

p>


0 commentaires

1
votes
my_array = [100, 101, 100, 102, 100, 100, 101, 100, 250, 251, 253, 260, 250, 200, 100, 100, 100, 100, 100, 100, 100, 100, 100, 120]


index_and_repetitions = lambda { |my_array|
  stk = {}
  previous = my_array[0]
  last_index = 0
  stk[last_index] = 1
  my_array.drop(0).each_with_index{|item, index|
    if item == previous
      stk[last_index] += 1
    else
      last_index = index
      stk[last_index] = 1
      previous = item
    end
  }
  stk
}

stk = index_and_repetitions.call(my_array)
puts stk.key(stk.values.max)
you can find benchmark results(compared to others answers) from here.

0 commentaires

1
votes

Je suppose que l'objectif est de trouver l'index du premier élément de la plus longue séquence d'éléments égaux dans le tableau donné.

b = a.last
  #=> [14, 15, 16, 17, 18, 19, 20, 21, 22] 
b.first
  #=> 14 

Ici, ce serait 14 code >, l'index de 100 qui est suivi de 8 autres 100's.

Nous pouvons le faire comme suit.

a = enum1.max_by { |_,a| a.size }

Les étapes sont les suivantes.

a = enum1.max_by { |v,a| a.size }
  #=> [100, [14, 15, 16, 17, 18, 19, 20, 21, 22]]

Nous pouvons voir les éléments qui seront générés par cet énumérateur en le convertissant en tableau.

enum1.to_a
  #=> [[100, [0]], [101, [1]], [100, [2]], [102, [3]], [100, [4, 5]],
  #    [101, [6]], [100, [7]], [250, [8]], [251, [9]], [253, [10]],
  #    [260, [11]], [250, [12]], [200, [13]],
  #    [100, [14, 15, 16, 17, 18, 19, 20, 21, 22]],
  #    [120, [23]]]

Continuer,

enum1 = enum0.chunk { |i| my_array[i] }
  #=> #<Enumerator: #<Enumerator::Generator:0x000058d8d09ec8a0>:each> 

Compte tenu de la valeur de retour de l'expression ci-dessus, enum1 pourrait être considéré comme un énumérateur composé , bien que Ruby n'ait pas ce concept. Voyons les valeurs générées par enum1 .

enum0.to_a
  #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
  #    17, 18, 19, 20, 21, 22, 23]

Continuation,

enum0 = my_array.each_index
  #=> #<Enumerator: [100, 101, 100,..., 100, 120]:each_index> 

Comme v n'est pas utilisé dans le bloc, cette expression s'écrirait habituellement:

my_array.each_index.chunk { |i| my_array[i] }.
         max_by { |_,a| a.size }.
         last.
         first
           #=> 14

La présence du trait de soulignement (une variable locale valide) signale au lecteur que cette variable de bloc n'est pas utilisée dans le calcul de bloc. Les deux dernières étapes sont les suivantes.

my_array = [100, 101, 100, 102, 100, 100, 101, 100, 250, 251, 253, 260, 250, 200,
            100, 100, 100, 100, 100, 100, 100, 100, 100,
            120]

Voir Enumerable # chunk et Enumerable # max_by .


0 commentaires