Skip to content

Commit d535050

Browse files
committed
Sync with underscore-java.
1 parent 85c5ae0 commit d535050

File tree

2 files changed

+62
-17
lines changed

2 files changed

+62
-17
lines changed

src/main/java/com/github/underscore/lodash/U.java

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ public class U<T> extends com.github.underscore.U<T> {
5151
private static String lower = "[a-z\\xdf-\\xf6\\xf8-\\xff]+";
5252
private static java.util.regex.Pattern reWords = java.util.regex.Pattern.compile(
5353
upper + "+(?=" + upper + lower + ")|" + upper + "?" + lower + "|" + upper + "+|[0-9]+");
54-
private static final Set<Character> NUMBER_CHARS = new HashSet<Character>(
55-
Arrays.asList('.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'));
5654

5755
static {
5856
String[] deburredLetters = new String[] {
@@ -1496,28 +1494,42 @@ public static List<String> stringToPath(final String string) {
14961494
}
14971495

14981496
@SuppressWarnings("unchecked")
1499-
private static <T> T baseGet(final Map<String, Object> object, final String path) {
1497+
private static <T> T baseGetAndSet(final Map<String, Object> object, final String path,
1498+
final Optional<Object> value) {
15001499
final List<String> paths = stringToPath(path);
15011500
int index = 0;
15021501
final int length = paths.size();
15031502

15041503
Object localObject = object;
1504+
Object savedLocalObject = null;
1505+
String savedPath = null;
15051506
while (localObject != null && index < length) {
15061507
if (localObject instanceof Map) {
15071508
Map.Entry mapEntry = getMapEntry((Map) localObject);
15081509
if (mapEntry != null && "#item".equals(mapEntry.getKey())) {
15091510
localObject = mapEntry.getValue();
15101511
continue;
15111512
}
1513+
savedLocalObject = localObject;
1514+
savedPath = paths.get(index);
15121515
localObject = ((Map) localObject).get(paths.get(index));
15131516
} else if (localObject instanceof List) {
1517+
savedLocalObject = localObject;
1518+
savedPath = paths.get(index);
15141519
localObject = ((List) localObject).get(Integer.parseInt(paths.get(index)));
15151520
} else {
15161521
break;
15171522
}
15181523
index += 1;
15191524
}
15201525
if (index > 0 && index == length) {
1526+
if (value.isPresent()) {
1527+
if (savedLocalObject instanceof Map) {
1528+
((Map) savedLocalObject).put(savedPath, value.get());
1529+
} else {
1530+
((List) savedLocalObject).set(Integer.parseInt(savedPath), value.get());
1531+
}
1532+
}
15211533
return (T) localObject;
15221534
}
15231535
return null;
@@ -1528,7 +1540,11 @@ private static Map.Entry getMapEntry(Map map) {
15281540
}
15291541

15301542
public static <T> T get(final Map<String, Object> object, final String path) {
1531-
return baseGet(object, path);
1543+
return baseGetAndSet(object, path, Optional.absent());
1544+
}
1545+
1546+
public static <T> T set(final Map<String, Object> object, final String path, Object value) {
1547+
return baseGetAndSet(object, path, Optional.of(value));
15321548
}
15331549

15341550
public static class FetchResponse {
@@ -2092,23 +2108,16 @@ private static Map<String, Object> replaceKeys(Map<String, Object> map) {
20922108
private static Object makeObject(Object value) {
20932109
final Object result;
20942110
if (value instanceof List) {
2095-
List<Map<String, Object>> values = newArrayList();
2111+
List<Object> values = newArrayList();
20962112
for (Object item : (List) value) {
2097-
values.add(replaceKeys((Map<String, Object>) item));
2113+
values.add(item instanceof Map ? replaceKeys((Map<String, Object>) item) : item);
20982114
}
20992115
result = values;
21002116
} else if (value instanceof Map) {
21012117
result = replaceKeys((Map<String, Object>) value);
21022118
} else {
21032119
String stringValue = String.valueOf(value);
2104-
boolean onlyNumbers = true;
2105-
for (char ch : stringValue.toCharArray()) {
2106-
if (!NUMBER_CHARS.contains(ch)) {
2107-
onlyNumbers = false;
2108-
break;
2109-
}
2110-
}
2111-
result = onlyNumbers ? Xml.stringToNumber(stringValue) : value;
2120+
result = stringValue.matches("^-?\\d*([.eE])?\\d+$") ? Xml.stringToNumber(stringValue) : value;
21122121
}
21132122
return result;
21142123
}
@@ -2136,7 +2145,7 @@ private static Object makeObjectSelfClose(Object value) {
21362145
if (value instanceof List) {
21372146
List<Object> values = newArrayList();
21382147
for (Object item : (List) value) {
2139-
values.add(replaceSelfCloseWithNull((Map) item));
2148+
values.add(item instanceof Map ? replaceSelfCloseWithNull((Map) item) : item);
21402149
}
21412150
result = values;
21422151
} else if (value instanceof Map) {

src/test/java/com/github/underscore/lodash/LodashTest.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,32 @@ public void at() {
432432
@Test
433433
public void get() {
434434
assertEquals("d", U.<String>get(
435-
(Map<String, Object>) U.fromJson("{\"a\":[{\"b\":{\"c\":\"d\"}}]}"), "a[0].b.c").toString());
435+
(Map<String, Object>) U.fromJson("{\"a\":[{\"b\":{\"c\":\"d\"}}]}"), "a[0].b.c"));
436+
}
437+
438+
/*
439+
_.set({"a":[{"b":{"c":"d"}}]}, "a[0].b.c", "e");
440+
// → "{a=[{b={c=e}}]}"
441+
*/
442+
@SuppressWarnings("unchecked")
443+
@Test
444+
public void set() {
445+
assertEquals("d", U.<String>set(
446+
(Map<String, Object>) U.fromJson("{\"a\":[{\"b\":{\"c\":\"d\"}}]}"), "a[0].b.c", "e").toString());
447+
assertEquals("{b={c=d}}", U.set(
448+
(Map<String, Object>) U.fromJson("{\"a\":[{\"b\":{\"c\":\"d\"}}]}"), "a[0]", "e").toString());
449+
Map<String, Object> map = U.newLinkedHashMap();
450+
Map<String, Object> map2 = U.newLinkedHashMap();
451+
Map<String, Object> map3 = U.newLinkedHashMap();
452+
map.put("a", map2);
453+
map2.put("#item", map3);
454+
map3.put("b", "c");
455+
assertEquals("c", U.<String>set(map, "a.b", "b").toString());
456+
assertNull(U.<String>set((Map<String, Object>) null, "a", "b"));
457+
assertNull(U.<String>set(U.<String, Object>newLinkedHashMap(), "a.b", "b"));
458+
Map<String, Object> map4 = U.newLinkedHashMap();
459+
map4.put("a", "b");
460+
assertNull(U.<String>set(map4, "a.b", "b"));
436461
}
437462

438463
@Test
@@ -615,9 +640,14 @@ public void xmlToJson() {
615640
+ " \"#omit-xml-declaration\": \"yes\"\n"
616641
+ "}",
617642
U.xmlToJson("<a><b/><b/></a>", U.Mode.REPLACE_SELF_CLOSING_WITH_NULL));
618-
Map<String, Object> map = new HashMap<String, Object>();
643+
Map<String, Object> map = U.newLinkedHashMap();
619644
map.put("-self-closing", "false");
620645
U.replaceSelfCloseWithNull(map);
646+
Map<String, Object> map2 = U.newLinkedHashMap();
647+
List<Object> list = U.newArrayList();
648+
list.add(U.newArrayList());
649+
map2.put("list", list);
650+
U.replaceSelfCloseWithNull(map2);
621651
}
622652

623653
@Test
@@ -685,6 +715,12 @@ public void removeMinusesAndConvertNumbers() {
685715
Map<String, Object> result4 = U.removeMinusesAndConvertNumbers(
686716
(Map<String, Object>) U.fromXml("<a><b c=\"1\"/></a>"));
687717
assertEquals("{a={b={c=1}}}", result4.toString());
718+
Map<String, Object> map = U.newLinkedHashMap();
719+
List<Object> list = U.newArrayList();
720+
list.add(U.newArrayList());
721+
map.put("list", list);
722+
Map<String, Object> result5 = U.removeMinusesAndConvertNumbers(map);
723+
assertEquals("{list=[[]]}", result5.toString());
688724
}
689725

690726
@SuppressWarnings("unchecked")

0 commit comments

Comments
 (0)