Gå til innhold

Finne alle mulig kombinasjoner fra Hash


Anbefalte innlegg

Hei,

 

Hvis jeg har følgende Hash:

{
 :message => ["hei", "halla"],
 :from => ["per", "pål"]
}

Hvordan kan jeg få dette resultatet:

[
 {:message => "hei", :from => "per"},
 {:message => "hei", :from => "pål"},
 {:message => "halla", :from => "per"},
 {:message => "halle", :from => "pål"}
]

 

Problemet er at den skal både støtte ulike størrelse på Array'et og kun String:

{
 :message => "op me",
 :from => ["Judofyr", "Per"],
 :to => ["#judofyr", "#judobot", "#testing"]
}

 

Har vridd hodet mitt, men finner ingen løsning :(

Lenke til kommentar
Videoannonse
Annonse

Da har jeg kommet opp med en stygg eval-versjon:

class Hash
 def possibilities
   hash = {}
   solutions = []
   i = ""

   each do |k,v|
     hash[k] = (v.is_a? Array) ? v : [v]
   end
   keys = hash.keys
   hash.length.times do |x|
     i << "hash[keys[#{x}]].each do |v#{x}|\n"
   end
   i << "solutions << {"
   length.times do |x|
     i << "keys[#{x}] => v#{x},"
   end
   i << "}\n"
   length.times do
     i << "end\n"
   end
   eval i
   solutions
 end
end

Lenke til kommentar

Her er en versjon i python:

def possibilities(d):
   def pos(items, index=0, temp={}, new=[]):
       key = items[index][0]
       if isinstance(items[index][1], basestring):
           items[index] = (key, [items[index][1]])
       end = False
       for value in items[index][1]:
           temp[key] = value
           if end:
               new.append(temp.copy())
               continue
           try:
               pos(items, index + 1, temp, new)
           except IndexError:
               new.append(temp.copy())
               end = True
       return new
   return pos(d.items())

d = {
'message' :["hei", "halla"],
'from' : ["Per", "Paal"],
}
l = possibilities(d)

Tenkte jeg skulle prøve å lage den i ruby, men orket ikke. Det går sikkert an å gjøre noe lignende i ruby.

Lenke til kommentar

Ok, men er ikke noe god på pseudo kode :p

 

Henter ut key, value parene i dict (hash i ruby) og gjør dem om til en liste (array) [(key, value), (key, value)]

Starter på index 0 i items og henter ut index 0 som er key.

Hvis valuen er en string, gjør den om til en liste.

Looper gjennom hvert element i value på den indexen.

lagrer key, value parene i temp.

Prøver å gjøre det samme som over på den neste indexen.

Hvis den neste indexen ikke eksisterer vil vi få en IndexError, det betyr at vi er på siste elemntet.

Hvis vi er på siste, append temp til new. Må bruke copy, hvis ikke vil temp bli endret når vi endrer den senere.

 

Er kanskje ikke akkurat pseudo kode men.

 

Denne funksjonen kaller seg selv mange ganger så det er litt vanskelig å følge alt som skjer, men når du har fått til en runde så vet man at det blir riktig neste runde også.

 

 

Prøvde meg på en ruby versjon:

k = {
:message => ["op me", "enfjne "],
:from => ["Judofyr", "Per"],
:to => ["#judofyr", "#judobot"]
}


def pos(items, index=0, temp={}, new=[])
   key = items[index]
   if key == nil
       new.push(temp.clone)
       return
   end
   key = key[0]
   items[index][1].each do |v|
       temp[key] = v
       pos(items, index + 1, temp, new)
   end
   return new
end

o = pos(k.to_a)
puts o

 

Fant ikke noen bra måte å sjekke om indexen fantes i farta, så du kan sikkert lage den litt finere. Sjekker heller ikke om noen av elementent er en string.

Tror den funker, men er ikke helt sikker, men det finner du ut.

 

Ruby var faktisk ganske kult. Tror jeg må prøve å lære meg det. :)

Lenke til kommentar

Tusen takk! Du er en snupp :)

 

Her er resultatet:

class Hash
 def possibilities(index = 0, temp = {}, new = [])
   items = to_a
   cur = items[index]
   return new.push(temp) if cur == nil
   key, value = cur
   value = [value] unless value.is_a? Array
   value.each do |v|
     temp[key] = v
     new = possibilities(index + 1, temp, new)
   end
   new
 end
end

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...