Quellcode durchsuchen

new: IntListGenerator - fix #4

Mariusz Sieroń vor 6 Jahren
Ursprung
Commit
dc10ecbab7

+ 4 - 0
assira/src/main/java/net/ranides/assira/collection/lists/IntList.java

@@ -18,6 +18,10 @@ import net.ranides.assira.collection.iterators.IntListIterator;
 public interface IntList extends IntCollection, List<Integer> {
     
     IntList EMPTY = IntArrays.asList();
+
+    static IntList of(int...values) {
+        return new IntArrayList(values);
+    }
 	
     void add(int index, int k);
 

+ 64 - 0
assira/src/main/java/net/ranides/assira/collection/lists/IntListGenerator.java

@@ -0,0 +1,64 @@
+package net.ranides.assira.collection.lists;
+
+import net.ranides.assira.text.StringTraits;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.IntStream;
+
+public class IntListGenerator {
+
+    private static final Pattern IS_RANGE = Pattern.compile("([0-9]+)-([0-9]+)");
+
+    public static IntList parse(String selector) {
+        return parse(Collections.emptyList(), Integer.MAX_VALUE, selector);
+    }
+
+    public static IntList parse(int size, String selector) {
+        return parse(Collections.emptyList(), size, selector);
+    }
+
+    public static IntList parse(List<String> names, String selector) {
+        return parse(names, names.size(), selector);
+    }
+
+    private static IntList parse(List<String> names, int size, String selector) {
+        IntList indexes = new IntArrayList();
+
+        Matcher hit;
+
+        for(String expr : selector.split(",")) {
+            int fieldIndex = names.indexOf(expr);
+            if(fieldIndex != -1) {
+                indexes.add(fieldIndex);
+            }
+            else if((hit = IS_RANGE.matcher(expr)).matches()) {
+                range(hit).filter(v -> v < size).forEach(indexes::add);
+            }
+            else if(StringTraits.isNumber(expr)) {
+                int i = Integer.parseInt(expr);
+                if(i > size) {
+                    throw new IndexOutOfBoundsException(i + " out of range: [0-" + size + ")");
+                } else {
+                    indexes.add(i);
+                }
+            }
+            else {
+                throw new IllegalArgumentException("Invalid index name: " + expr);
+            }
+        }
+        return indexes;
+    }
+
+    private static IntStream range(Matcher range) {
+        int a = Integer.parseInt(range.group(1));
+        int b = Integer.parseInt(range.group(2));
+        if (a <= b) {
+            return IntStream.rangeClosed(a, b);
+        } else {
+            return IntStream.rangeClosed(b, a).map(v -> b + a - v);
+        }
+    }
+}

+ 28 - 0
assira/src/test/java/net/ranides/assira/collection/lists/IntListGeneratorTest.java

@@ -0,0 +1,28 @@
+package net.ranides.assira.collection.lists;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class IntListGeneratorTest {
+
+    @Test
+    public void parseInt() {
+        assertEquals(IntList.of(1,2,3,4,8,9,10), IntListGenerator.parse("1-4,8-10"));
+        assertEquals(IntList.of(1,2,3,4,10,9,8), IntListGenerator.parse("1-4,10-8"));
+    }
+
+    @Test
+    public void parseRangeLimit() {
+        assertEquals(IntList.of(1,2,3,4), IntListGenerator.parse(5, "1-14"));
+    }
+
+    @Test
+    public void parseNames() {
+        List<String> names = Arrays.asList("a", "b", "c", "d", "e", "f");
+        assertEquals(IntList.of(1,2,5,4,0,3), IntListGenerator.parse(names, "1-2,f,e,a,3"));
+    }
+}