2013-11-07 2 views
0

У меня есть список массива со значениями, такими каксписка разделов с дозорным значением

{ "november", "a","b","c","d", "december", "i","j","k", "april", "g","h" } 

Каков наилучшим способом разделить его, так что я могу иметь различные массивы на основе months.for например

List<String> novemberArray={"a","b","c","d"} 

и

List<String> decemberArray={"i","j","k"}` 

и т.д ..

Я получаю этот список от разбора html-страницы с Jsoup.

Elements tableRowElements = tableElements.select(":not(thead) tr"); 
for (int i = 0; i < tableRowElements.size(); i++) { 
    Element row = tableRowElements.get(i); 
    System.out.println("row : "); 
    Elements rowItems = row.select("tr"); 
    for (int j = 1; j < rowItems.size(); j++) { 
    System.out.println(rowItems.get(j).text()); 
    myList.add(rowItems.get(j).text()); 
    } 
} 

MyList имеет значения { "november", "a","b","c","d", "december", "i","j","k", "april", "g","h" } Список является динамическим и я не имею никакого контроля на позиции в списке. Использование вспомогательных индексов не поможет, потому что они часто меняются.

+1

вы можете разместить код, показывающие текущий подход? –

+0

Если у вас есть контроль над массивом, который вы получаете, то я ** сильно ** предлагаю вам изменить соответствие, более подробную информацию. Один из способов: {"November = a, b, c, d; December = i, j, k"} и т. Д. Это поможет вам более четко разделить ваш массив и быть более читаемым. –

+0

imho лучше всего то, что вы можете сделать, это заменить карту со списком, где она изначально создана – user902383

ответ

1

Одним из способов является найти начало и конец индекса и использовать subList(int fromIndex, int toIndex), чтобы получить представление о части исходного списка.

Из API:

Возвращает представление части этого списка между указанными fromIndex, включительно, и toIndex, эксклюзивные. (Если fromIndex и toIndex равны, возвращенный список пуст.) Возвращаемый список: , подкрепленный этим списком, поэтому неструктурные изменения в возвращенном списке отражены в этом списке и наоборот. Возвращенный список поддерживает все дополнительные операции с списком, поддерживаемые этим списком.

+1

i dont думаю, что позиции для названия месяца должны быть постоянными –

+0

@HussainAkhtarWahid Конечно, я сказал: «Найдите начало и конец расстояния». чтобы реализовать логику, чтобы узнать, есть ли у нее какие-либо месяцы, а затем использовать subList – JNL

0

Создайте карту String в список, чтобы удерживать месяцы в качестве ключей и списка ваших значений a, b, c и т.д. в качестве значений.

Пройдите через ArrayList и проверьте каждую запись на список или набор строк месяца («Январь», «Февраль», ...), каждый раз, когда вы сталкиваетесь с положительным совпадением, установите переменную currentMonth в сопоставить месяц и добавить/обновить соответствующую запись списка на карте для каждой из следующих несетевых переменных.

Псевдо Код:

If (entry is month) { 
    currentMonth = entry; 
} else { 
    List entries = monthMap.get(currentMonth) == null ? new ArrayList<>() : monthMap.get(currentMonth) 
    entries.add(entry) 
    monthMap.put(currentMonth, entries) 
} 
+0

Не нужно переставлять список на карту, если он уже был там. –

+0

Да, просто обработайте случай, когда он еще не был там, для полноты. – HughWPHamill

1

Так у вас есть ArrayList, содержащие данные ("a", "b", т.д.), А также значения дозорных ("november" и т.д.)? Комментарий Ореля Эраки на месте, вы просите о проблемах с такими данными. Если вы можете, вы найдете гораздо меньше боли, избегая этой методологии полностью.

Но, предполагая, что вы не можете изменить его, вот как вы можете с ним справиться. Я использую GuavaMultimap, и я настоятельно рекомендую вам тоже, но вы можете заменить его на HashMap<String, ArrayList<String>> с помощью небольшого дополнительного шаблона.

public ListMultimap<String,String> removeSentinels(List<String> ls, 
                Set<String> sentinels) { 
    String currentSentinel = null; 
    ArrayListMultimap<String,String> map = ArrayListMultimap.create(); 
    for(String s : ls) { 
    if(sentinels.contains(s)) { 
     currentSentinel = s; 
    } else { 
     /* 
     Note if the list doesn't start with a sentinel value, it will put items in the 
     null entry. You could instead do a null check here and raise an exception, or 
     use an ImmutableListMultimap which forbids null keys or values. 
     */ 
     map.put(currentSentinel, s); 
    } 
    } 
    return map; 
} 

Вы можете получить элементы с List<String> novemberList = map.get("november"); и так далее.


Ваш пример JSoup объясняет основную концептуальную проблему. Вы берете данные 2D-таблицы и читаете ее в 1D-список. Такое же поведение, описанное выше, можно использовать для более чистого анализа этих данных таблицы в Multimap с самого начала, избегая необходимости повторного анализа позже (в качестве альтернативы, Guava также предлагает интерфейс Table, но это, вероятно, слишком велико для вашего использования -случае):

public ListMultimap<String,String> tableToMap(Document doc) { 
    Elements trElems = doc.select(":not(thead) tr"); 
    ArrayListMultimap<String,String> map = ArrayListMultimap.create(); 
    for(Element tr : trElems) { 
    // I assume you meant td, a <tr> shouldn't contain <tr>'s 
    Elements tdElems = tr.select("td"); 
    String month = tdElems.get(1).text(); // You skip index 0, presumably intentionally 
    for(int i = 2; i < tdElems.size(); i++) { 
     map.put(month, tdElems.get(i).text()); 
    } 
    } 
    return map; 
} 
+0

Thankyou так много. Гуава и ваше предложение работали как шарм. Awesome – user2679612

+0

Рад, что я мог бы помочь, у Guava есть очень классная функциональность, стоит потратить время, чтобы полностью изучить их документы. – dimo414

-1

здесь мирянин подход

import java.util.*; 

public class One { 
    public static void main(String[] args) 
    { 
     String[] inputArray = new String[]{ "november", "a","b","c","d","december", "i","j","k","april", "g","h"}; 
     List<String> monthNames = new ArrayList<String>(); 
     List<String> monthNamesOutput = new ArrayList<String>(); 
     List<String> alphabetsOutput = new ArrayList<String>(); 
     monthNames.add("january"); 
     monthNames.add("february"); 
     monthNames.add("march"); 
     monthNames.add("april"); 
     monthNames.add("may"); 
     monthNames.add("june"); 
     monthNames.add("july"); 
     monthNames.add("august"); 
     monthNames.add("september"); 
     monthNames.add("october"); 
     monthNames.add("november"); 
     monthNames.add("december"); 
     for(String temp:inputArray) 
     { 
      if(monthNames.contains(temp)) 
      { 
       monthNamesOutput.add(temp); 
      } 
      else 
      { 
       alphabetsOutput.add(temp); 
      } 
     } 
     System.out.println(monthNamesOutput); 
     System.out.println(alphabetsOutput); 
    } 
} 
+0

-1: выполнение содержит проверки против 'List' является расточительным. Вместо этого используйте 'Set'. – dimo414

+0

Я использовал список, потому что я был не уверен, должен ли выходной массив иметь месячные имена только один раз или можно получить повторение –

+0

Я имею в виду ваш список 'monthNames'. Вы выполняете поиск O (n) в отношении этого списка для каждого элемента в списке, выбирая производительность O (n^2). – dimo414

Смежные вопросы