Trier un tableau selon les éléments d'un autre ensemble
J'ai un tableau d'id de
a1 = [1, 2, 3, 4, 5]
et j'ai un autre tableau d'objets avec des id dans un ordre aléatoire
a2 = [(obj_with_id_5), (obj_with_id_2), (obj_with_id_1), (obj_with_id_3), (obj_with_id_4)]
Maintenant, j'ai besoin de trier a2 en fonction de l'ordre d'id dans a1. Donc a2 doit maintenant devenir:
[(obj_with_id_1), (id_2), (id_3), (id_4), (id_5)]
a1 peut être [3, 2, 5, 4, 1] ou dans n'importe quel ordre, mais a2 doit correspondre à l'ordre de id dans a1.
Je fais comme ceci:
a1.each_with_index do |id, idx|
found_idx = a1.find_index { |c| c.id == id }
replace_elem = a2[found_idx]
a2[found_idx] = a2[idx]
a2[idx] = replace_elem
end
Mais c'est toujours susceptible de s'exécuter en O(n^2) si l'ordre des éléments de a2 est exactement l'inverse de a1. Quelqu'un peut-il me dire de la façon la plus efficace de tri a2?
Vous devez vous connecter pour publier un commentaire.
Je crois que le temps d'exécution O(n)
hash_object = objects.index_by(&:object_id)
[nil, nil, nil, nil, nil]
à moins que le object_ids se trouvent être les numéros 1 à 5. Pour le faire fonctionner, vous avez besoin pour obtenir le object_ids et de les trier, ce qui ne sera pas mieux queobjects.index_by(&:object_id)
. Aussi, il n'est pas nécessaire pour expliquer le O(n) demande ici, mais note que le O(n log n) limite inférieure s'applique uniquement à la comparaison de toutes sortes.O(2n)
? Pourquoi importe-t-il-qui se soucie vraiment de big-O de notation?Je serais surpris si quelque chose est beaucoup plus rapide que le moyen le plus évident:
Benchmark.bm { |t| t.report('test1') { x.index_by { |c| c }.values_at(*x2).compact } t.report('test2') { x.sort_by { |v| x2.index v } } }
test1 réel: 0.000709 test2 réel: 0.048563bsearch_index
donc si vous passez à cela, l'indice lui-même est en O(logn). Compte tenu de ce qui est fait n fois pour a2, il sera en O(nlogn). @isqad la solution est préférable. Mais il crée des 3 objets. 1. index_by de hachage, 2. values_at tableau 3. compact un autre tableau. Vous pouvez simplifier en utilisantcompact!
. C'est donc l'espace-temps de la complexité à ce point.J'aime la accepté de répondre, mais dans ActiveSupport il est index_by qui fait de la création de la première hachage encore plus facile. Voir Façon la plus propre de créer un Hachage à partir d'un Tableau
En fait, vous pourriez le faire en une seule ligne depuis Énumérable prend en charge index_by ainsi:
Inspiré par Eric Woodruff Répondre, je suis venu avec la suite de la vanille Ruby solution:
Documentation de la méthode:
a2
avoir la même valeur de "id". La question n'est pas que les id sont uniques, encore de réponses à certaines questions, y compris celle qui est sélectionnée, dépendent de l'id est unique.