#scala #functional-programming
#scala #функциональное программирование
Вопрос:
Я новичок в функциональном языке программирования и нуждаюсь в помощи для решения одной из моих проблем.
Мне нужно создать карту между двумя кортежами последовательностей :
A = tuple1(tuple1(tuple1(x,y),z),a)
B = tuple2(tuple2(tuple2(1,2),3),4)
теперь мне нужно что-то вроде приведенного ниже :
C = ((x, 1), (y, 2), (z,3), (a, 4)) и если я ищу, скажем, x, тогда мне нужно получить 1 ;
Количество вхождений кортежей неизвестно, но структура обоих кортежей будет одинаковой. Я не мог понять и сопоставить решение для подобных вопросов в stackoverflow. Поэтому решение с объяснением будет полезно
Комментарии:
1. Я думаю, что правильное решение — избегать создания вложенных структур кортежей, подобных этой, в первую очередь. С ними нелегко работать. Вместо этого создайте списки, и вы можете использовать
zip
withtoMap
, чтобы получить то, что вы хотите.2. Можете ли вы объяснить немного больше, чего вы пытаетесь достичь? Важно ли использовать вложенные кортежи (или даже вложенные списки)?
3. Мне необходимо и, возможно, сейчас невозможно изменить структуру.. Я занимаюсь разработкой компилятора, и это требуется для моего дизайна интерпретатора. При этом мне нужно отслеживать аргументы функции, т.Е. идентификаторы передаваемых значений.. Может быть немного сложно объяснить общую структуру .
4. Если вы находитесь на этапе разработки вашего компилятора, вы можете (и, вероятно, должны) изменить его. Использование кортежа для карты от имени идентификатора до значения является разумным, но вложенные кортежи кажутся дизайнерским запахом
5. Спасибо вам, ребята, за помощь в этом. Особенно полезным было решение @Jasper-M. Я несколько модифицировал, чтобы соответствовать моим потребностям. Это было нелегко изменить, как некоторые из вас предложили, потому что для этого мне нужно приложить усилия, чтобы изменить этап проверки вместе с синтаксическим анализатором. Теперь я понимаю, как мне следовало подумать о синтаксическом анализаторе.
Ответ №1:
Я думаю, что это делает (уродливый) трюк.
def toMap(x: (Any,String), y: (Any,Int)): Map[String, Int] = {
@tailrec
def rec(x: (Any,String), y: (Any,Int), map: Map[String, Int]): Map[String, Int] =
x match {
case (a: String, b) =>
val (c: Int, d) = y
map Map(a -> c, b -> d)
case (a: (Any,String), b) =>
val (c: (Any,Int), d) = y
rec(a, c, map Map(b -> d))
}
rec(x, y, Map.empty[String, Int])
}
Предполагая, что вы хотите использовать его следующим образом:
scala> val a = ((("x","y"),"z"),"a")
a: (((String, String), String), String) = (((x,y),z),a)
scala> val b = (((1,2),3),4)
b: (((Int, Int), Int), Int) = (((1,2),3),4)
scala> toMap(a,b)
res1: Map[String,Int] = Map(a -> 4, z -> 3, x -> 1, y -> 2)