2016-10-13 2 views
0

Я пытаюсь разбить список целых чисел на меньшие массивы (диапазоны) значениями из другого списка. Так, например, наличие массива с такими значениямиSplit ArrayList из целых чисел с использованием RxJava

[100, 10, 4000, 9, 3000, 1024, 15, 660, 999] 

И массив значений для разделения по.

[20, 300, 500, 1000, 10000] 

Я хочу получить массивы со значениями, которые меньше соответствующих значений. Как

20 -- [9, 10, 15] // (value from first array < 20) 
300 -- [100] // (20 <= value < 300) 
500 -- [] // (300 <= value < 500) 
1000 -- [660, 999] // (500 <= value < 1000) 
10000 -- [1024, 3000, 4000] // (1000 <= value < 10000) 

Есть ли способ реализовать это с помощью RxJava? Или любой быстрый алгоритм для этого?

+2

Вы пытались что-нибудь еще? – ItamarG3

+0

У меня есть некоторые идеи, как реализовать это не слишком оптимальным способом, просто перебирая массив значений и сравнивая его с каждым элементом в массиве диапазонов. Но это кажется не слишком оптимальным. – dbulgakov

+0

Может быть, лучший способ сравнить отсортированный список значений с отсортированным массивом диапазонов, но я понятия не имею, как это сделать с помощью RxJava – dbulgakov

ответ

2

Использование java8 потоков,

List<Integer> numbers = Arrays.asList(100, 10, 4000, 9, 3000, 1024, 15, 660, 999); 
    List<Integer> range = Arrays.asList(20, 300, 500, 1000, 10000); // sorted 
    Function<Integer, Integer> between = n -> { 
     for (Integer in : range) { 
      if (in >= n) 
       return in; 
     } 
     return -1; 
    }; 
    Map<Integer, List<Integer>> grouped = numbers.stream().collect(Collectors.groupingBy(between)); 
    System.out.println(grouped); 

OUTPUT

{10000=[4000, 3000, 1024], 20=[10, 9, 15], 1000=[660, 999], 300=[100]} 

вы можете предоставить поставщику в качествеTreeMap в groupingBy, чтобы получить результат в отсортированном.

UPDATE

Для сортировки по ключу вывода

Map<Integer, List<Integer>> grouped = numbers.stream().collect(Collectors.groupingBy(between, TreeMap::new, Collectors.mapping(k -> k, Collectors.toList()))); 

{20=[10, 9, 15], 300=[100], 1000=[660, 999], 10000=[4000, 3000, 1024]} 
+0

Спасибо. Это то, что я искал. – dbulgakov

+0

@dbulgakov приветствуется, обновленный ответ с кодом сортировки – Saravana

1

Это похоже на работу:

public static void main(String[] args) { 
     List<Integer> list = new ArrayList<Integer>(); 
     list.add(100); 
     list.add(10); 
     list.add(4000); 
     list.add(9); 
     list.add(3000); 
     list.add(1024); 
     list.add(15); 
     list.add(660); 
     list.add(999); 
     int[] splitValues = new int[]{20,300,500,1000,10000}; 
     int prev = 0; 
     //100, 10, 4000, 9, 3000, 1024, 15, 660, 999 
     Collections.sort(list); 
     Map<Integer, Integer[]> map = new HashMap<Integer,Integer[]>(); 
     for (int i = 0; i < splitValues.length; i++) { 
      for (int j=prev;j<list.size();j++) { 
       if(splitValues[i]<list.get(j)){ 
        addRecord(map,list,j, splitValues[i],prev); 
        prev = j; 
        break; 
       } 
      } 
     } 
     System.out.println(map); 
    } 

    private static void addRecord(Map<Integer, Integer[]> map, List<Integer> list, int j, int index, int start) { 
     try { 
      list = list.subList(start, j);   
     } catch (Exception e) { 
      System.out.println("boo"); 
     } 

     Integer[] arr = new Integer[j-start]; 
     list.toArray(arr); 
     map.put(index, arr); 

    } 

Единственная проблема заключается в отображении его

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