Как я сортирую набор Списков в лексикографическом порядке в Scala?

Ваш вопрос немного неясен.

Если ваш вопрос только в том, возможно ли это или нет:

Нет! (по крайней мере, не так, как вы ожидаете)

что-нибудь в этом блоке: 118]

if (GUILayout.Button("Search"))
{
     ...
}

выполняется только в тот момент, когда кнопка фактически нажата.

1110 Итак, вы должны сделать это так, как вы уже это сделали. Возможно добавление дополнительной проверки для отображения только тех полей, если список не пуст:

// only show the button while the list is empty
if(gameobjecttest.Count == 0)
{
    if (GUILayout.Button("Search"))
    {
         ...
    }

    // skip the rest
    return;
}

// otherwise show the list
EditorGUILayout.BeginHorizontal();
{
    scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(300), GUILayout.Height(400));
    {
        foreach (GameObject go in gameobjecttest)
        {
            EditorGUILayout.LabelField(go.name);
        }
    }
    EditorGUILayout.EndScrollView();
}
EditorGUILayout.EndHorizontal();

(я обычно добавляю эти { } для очистки кода немного)

[1112 ] Или удерживайте кнопку, но вместо этого отключите ее

EditorGUI.BeginDisabledGroup(gameobjecttest.Count != 0);
{
    if (GUILayout.Button("Search"))
    {
         ...
    }
}
EditorGUI.EndDisabledGroup();
11
задан Scott Morrison 17 September 2010 в 01:52
поделиться

4 ответа

Просто, потому что я уже реализовал это иначе, вот нерекурсивная версия, которая не использует return:

new Ordering[Seq[String]]() {
  override def compare(x: Seq[String], y: Seq[String]): Int = {
    x.zip(y).foldLeft(None: Option[Int]){ case (r, (v, w)) =>
        if(r.isDefined){
          r
        } else {
          val comp = v.compareTo(w)
          if(comp == 0) None
          else Some(comp)
        }
      }.getOrElse(x.size.compareTo(y.size))
    }
  }
0
ответ дан 3 December 2019 в 01:51
поделиться

(11 минут назад я действительно не «Не знаю, как это сделать, я надеюсь, что это нормально, чтобы ответить на мой вопрос.»

implicit def List2OrderedList[A <% Ordered[A]](list1: List[A]): Ordered[List[A]] = { 
    new Ordered[List[A]] {
        def compare(list2: List[A]): Int = {
            for((x,y) <- list1 zip list2) {
                val c = x compare y
                if(c != 0) return c
            }
            return list1.size - list2.size
        }
    }
}

Здесь важно отметить « граница просмотра » A <% Ordered [A ] , что гарантирует, что A не нуждается в себе Ordered [A] , просто существует способ выполнить это преобразование. К счастью, объект библиотеки Scala Predef имеет неявное преобразование из Int s в RichInt s, которые, в частности, являются Ordered [Int] с.

Остальная часть кода просто реализует лексикографический порядок.

5
ответ дан 3 December 2019 в 01:51
поделиться

В версии 2.8 вы должны иметь возможность просто выполнять collection.sorted . sorted принимает неявный параметр упорядочения . Любой тип, реализующий Ordered , имеет соответствующее Ordering (благодаря неявному преобразованию Ordering.ordered ). Также существует неявный Ordering.Iterable , который заставляет Iterable [T] иметь Ordering , если T имеет Ordering] .

Однако, если вы попробуете это, это не сработает:

scala> def sort[A <: Ordered[A]](coll: List[List[A]]) = coll.sorted

<console>:5: error: could not find implicit value for parameter ord: Ordering[List[A]]
       def sort[A <: Ordered[A]](coll: List[List[A]]) = coll.sorted
                                                             ^

Вам нужно явно указать, что вы хотите Ordering [Iterable [A]] :

def sort[A <: Ordered[A]](coll: List[List[A]]) = coll.sorted[Iterable[A]]

Я не уверен, почему компилятор не может найти Ordering [Iterable [A]] , если тип элемента коллекции - List [A] .

4
ответ дан 3 December 2019 в 01:51
поделиться

На основе комментария Даниэля, вот рекурсивная версия:

implicit def toOrdered[A <% Ordered[A]](list1: List[A]): Ordered[List[A]] = { 
  @scala.annotation.tailrec
  def c(list1:List[A], list2:List[A]): Int = {
    (list1, list2) match {
      case (Nil, Nil) => 0
      case (x::xs, Nil) => 1
      case (Nil, y::ys) => -1
      case (x::xs, y::ys) => (x compare y) match {
        case 0 => c(xs, ys)
        case i => i
      }
    }
  }
  new Ordered[List[A]] {
    def compare(list2: List[A]): Int = c(list1, list2)
  }
}

Что касается комментария: Раньше я думал, что это дело вкуса. Иногда легче проверить правильность рекурсивной функции, и, конечно же, ваша версия достаточно коротка, поэтому нет веских причин для предпочтения рекурсивной функции.

Однако меня заинтриговали последствия для производительности. Поэтому я попытался протестировать его: см. http://gist.github.com/468435 . Я был удивлен, увидев, что рекурсивная версия работает быстрее (при условии, что я правильно выполнил тест). Результаты остаются верными для списка длиной около 10.

2
ответ дан 3 December 2019 в 01:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: