• Login

Mustamakkara

Blutwurst der Verdammnis

  • "Mustamakkara" started this thread

Motto: Zuhause ist da, wo du deine Schuhe ausziehen kannst.

  • Send private message

1

Thursday, February 6th 2020, 9:52am

Ist ein Array in einem anderen Array?

Guten Morgen, Guest :musta:

Ich schreibe derzeit an meinem ersten eigenen, kuhlen Script - dazu ein andermal mehr.

Dabei bin ich jetzt auf folgendes Problem gestoßen: Ich möchte gerne überprüfen, ob ein Array in einem anderen Array enthalten ist. Über die Schnittmenge oder Subtraktion zu gehen, funktioniert leider nicht, denn
  1. enthalten meine Arrays auch doppelte Elemente
  2. möchte ich auch überprüfen, ob die Reihenfolge identisch ist

Meine neue Methode soll also folgendermaßen arbeiten:

Ruby Source code

1
2
3
4
5
6
7
a1 = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
a2 = [5, 4, 3]
a1.new_includes?(a2) #=> return false
a2 = [4, 5, 2, 3]
a1.new_includes?(a2) #=> return false
a2 = [4, 5, 1, 2]
a1.new_includes?(a2) #=> return true


Bin ich einfach nur blind und es gibt eine solche Methode schon? Oder gibt es eine einfache Möglichkeit, die ich gerade übersehe? Oder ist es wirklich so kompliziert, wie es mir gerade vorkommt?
:musta:

2

Thursday, February 6th 2020, 5:47pm

Hi,

würde es spontan so machen:

array1 = [1, 2, 2, 3, 4, 5, 2]
array2 = [2, 3, 4]

Ruby Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
check = array1 & array2
return false unless check == array2
 
check = array2[0]
array1.each_with_index do |e, i|
 
next unless check == e
check2 = array1.slice(i, i + array2.size - 1)
next unless check2 == array2
return true
 
end 
return false


Ungetestet, aber sollte von der Grundidee gehen. Kurze Erklärung:

Zunächst wird per

Ruby Source code

1
&
Methode festgestellt, ob überhaupt jeder Wert aus Array2 in Array1 vorhanden ist.
Die doppelten Einträge werden dabei gefiltert, ist hier aber uninteressant.
Es soll ja gar nicht geprüft werden, wenn nicht alle Werte aus dem Array vorkommen.

Anschließend wird der Wert von Index 0 aus dem Array2 in die Variable check geschrieben.
Danach wird durch das Array1 mit der

Ruby Source code

1
each_with_index
Methode iteriert mit Rückgabe von Wert und dazugehörigen Index.
Ist der Wert nicht = der Variable check, geht es mit next weiter zum nächsten Wert in Array1.
Ist ein Wert = der check Variable, schneidet er mit der

Ruby Source code

1
slice
Methode einen Bereich ab dem Treffer aus Array1 aus und
fügt die Werte in ein neues Array, hier Check2. Der Bereich startet ab dem Treffer und ist so groß, wie das Array2.
Jetzt wird verglichen, ob das Array2 dem ausgeschnittenen Bereich gleicht. Wenn nicht, geht es wieder mit den nächsten Wert in Array1 weiter.
Das geht so weiter bis er entweder die exakte Zahlenfolge gefunden hat und dann true zurückgibt, oder eben ein false zurückgibt.

Mit den zwei Array Beispielen würde er true liefern, da er den bereich ab dem zweiten Index in Array 1 ausschneidet.
Also im Array1 schneidet er die fett markierten aus [1, 2, 2, 3, 4, 5, 2] und packt diese in das neue check2 Array.
Dann gleicht er Array2 mit check2 ab und gibt true weil Array2[2, 3, 4] = check2[2, 3, 4].

Mustamakkara

Blutwurst der Verdammnis

  • "Mustamakkara" started this thread

Motto: Zuhause ist da, wo du deine Schuhe ausziehen kannst.

  • Send private message

3

Friday, February 7th 2020, 8:52am

Vielen Dank, die Idee mit dem Slice ist ziemlich gut. Die Methode hat zwar so nicht immer korrekt funktioniert, aber ich habe jetzt eine, die geht:


Ruby Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Array
 
  def compare?(array2)
    check = array2 & self
    return false unless check == array2&array2
    check = array2[0]
    self.each_with_index do |e, i|
      next unless check == e
      check2 = self.slice(i, array2.size)
      next unless check2 == array2
      return true
    end 
    return false
  end
 
end


Korrekturen:

Bei der Schnittmenge muss der kleinere Array vorne stehen. Die resultierenden Elemente sind zwar gleich, aber die Sortierung entspricht immer dem zuerst genannten, und [2, 3, 4] != [3, 2, 4]. Zudem müssen beim Vergleich der Schnittmengen auch die doppelten Elemente aus dem kleinen Array gelöscht werden. Das mache ich, indem er die Schnittmenge mit sich selbst bildet.

Und statt

Ruby Source code

1
array1.slice(i, i + array2.size - 1)
reicht ein

Ruby Source code

1
array1.slice(i, array2.size)
, denn der zweite Parameter von Array#slice gibt nicht den Index des letzten Elements an, sondern die Länge des Stücks, welches wir ausschneiden.

Auf jeden Fall Danke für deine Hilfe :) Jetzt muss ich nur noch ein paar Performanceprobleme in den Griff kriegen und dann steht mein erstes, eigenes Script :D
:musta:

This post has been edited 1 times, last edit by "Mustamakkara" (Feb 7th 2020, 8:52am)


4

Friday, February 7th 2020, 10:45am

Moin,

upps, habe ich wohl überlesen, dass beide Arrays doppelte Einträge besitzen können. Bin nur von dem Ersten ausgegangen :D.
Danke für die restlichen Hinweise. Ist auch für mich relevant, da ich mich aktuell in Ruby einarbeite um mehr in RGSS kreieren zu können.
Bin stolz auf mich, dass es grundsätzlich so funktioniert :epic: .

Similar threads

Social bookmarks