mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-10-27 20:34:16 +00:00
XOMW: Add PHP array-diff and array-diff-key [#632]
This commit is contained in:
parent
ebe82bea6a
commit
04c499ce3e
@ -30,10 +30,14 @@ import gplx.core.brys.Bry_bfr_able;
|
||||
import gplx.core.strings.String_bldr;
|
||||
import gplx.core.strings.String_bldr_;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
// REF.PHP: https://www.php.net/manual/en/language.types.array.php
|
||||
// also has static functions; REF.PHP: https://www.php.net/manual/en/ref.array.php
|
||||
// REF.PHP:https://www.php.net/manual/en/language.types.array.php
|
||||
// also has static functions; REF.PHP:https://www.php.net/manual/en/ref.array.php
|
||||
public class XophpArray<T> implements Bry_bfr_able, Iterable<T> {
|
||||
private final Ordered_hash hash = Ordered_hash_.New();
|
||||
private int newMemberIdx;
|
||||
@ -138,6 +142,9 @@ public class XophpArray<T> implements Bry_bfr_able, Iterable<T> {
|
||||
XophpArrayItm itm = (XophpArrayItm)hash.Get_by(key);
|
||||
return itm == null ? null : (T)itm.Val();
|
||||
}
|
||||
public XophpArrayItm Get_by_itm(String key) {
|
||||
return (XophpArrayItm)hash.Get_by(key);
|
||||
}
|
||||
public void Set(int key, Object val) {
|
||||
this.Set(XophpArrayItm.NewInt(key, val));
|
||||
}
|
||||
@ -160,6 +167,9 @@ public class XophpArray<T> implements Bry_bfr_able, Iterable<T> {
|
||||
hash.Del(itm.Key());
|
||||
}
|
||||
}
|
||||
public void Del_by(String key) {
|
||||
hash.Del(key);
|
||||
}
|
||||
public XophpArrayItm[] To_ary() {
|
||||
return (XophpArrayItm[])hash.To_ary(XophpArrayItm.class);
|
||||
}
|
||||
@ -309,7 +319,7 @@ public class XophpArray<T> implements Bry_bfr_able, Iterable<T> {
|
||||
return len == 0 ? null : ((XophpArrayItm)array.hash.Get_at(len - 1)).Val();
|
||||
}
|
||||
|
||||
// REF.PHP: https://www.php.net/manual/en/function.array-values.php
|
||||
// REF.PHP:https://www.php.net/manual/en/function.array-values.php
|
||||
public static XophpArray array_values(XophpArray array) {
|
||||
XophpArray rv = new XophpArray();
|
||||
int len = array.Len();
|
||||
@ -482,7 +492,7 @@ public class XophpArray<T> implements Bry_bfr_able, Iterable<T> {
|
||||
return sb.To_str_and_clear();
|
||||
}
|
||||
|
||||
// REF.PHP: https://www.php.net/manual/en/function.in-array.php
|
||||
// REF.PHP:https://www.php.net/manual/en/function.in-array.php
|
||||
public static boolean in_array(Object needle, XophpArray haystack) {return in_array(needle, haystack, false);}
|
||||
public static boolean in_array(Object needle, XophpArray haystack, boolean strict) {
|
||||
// if strict, cache needleType
|
||||
@ -519,7 +529,7 @@ public class XophpArray<T> implements Bry_bfr_able, Iterable<T> {
|
||||
return false;
|
||||
}
|
||||
|
||||
// REF.PHP: https://www.php.net/manual/en/function.array-shift.php
|
||||
// REF.PHP:https://www.php.net/manual/en/function.array-shift.php
|
||||
// Returns the shifted value, or NULL if array is empty or is not an array.
|
||||
public static Object array_shift(XophpArray array) {
|
||||
if (array == null) {
|
||||
@ -544,7 +554,7 @@ public class XophpArray<T> implements Bry_bfr_able, Iterable<T> {
|
||||
return itms[0].Val();
|
||||
}
|
||||
|
||||
// REF.PHP: https://www.php.net/manual/en/function.array-filter.php
|
||||
// REF.PHP:https://www.php.net/manual/en/function.array-filter.php
|
||||
public static final int ARRAY_FILTER_USE_BOTH = 1, ARRAY_FILTER_USE_KEY = 2, ARRAY_FILTER_USE_VAL = 0; // XO:USE_VAL is not PHP
|
||||
public static XophpArray array_filter(XophpArray array) {return array_filter(array, NULL_CALLBACK, 0);}
|
||||
public static XophpArray array_filter(XophpArray array, XophpCallback callback) {return array_filter(array, callback, 0);}
|
||||
@ -578,4 +588,70 @@ public class XophpArray<T> implements Bry_bfr_able, Iterable<T> {
|
||||
return !XophpObject_.empty_obj(arg);
|
||||
}
|
||||
}
|
||||
// REF.PHP:https://www.php.net/manual/en/function.array-diff.php
|
||||
public static XophpArray array_diff(XophpArray array1, XophpArray array2, XophpArray... arrays) {
|
||||
// remove elements
|
||||
Map<String, List<String>> valMap = array_diff__build_val_map(array1);
|
||||
int array1_len = array1.Len();
|
||||
array_diff__remove_common_vals(valMap, array1, array2);
|
||||
for (XophpArray array : arrays) {
|
||||
// update map, if array contents changed
|
||||
if (array1_len != array1.Len()) {
|
||||
valMap = array_diff__build_val_map(array1);
|
||||
array1_len = array1.Len();
|
||||
}
|
||||
array_diff__remove_common_vals(valMap, array1, array);
|
||||
}
|
||||
return array1;
|
||||
}
|
||||
private static Map<String, List<String>> array_diff__build_val_map(XophpArray array) {
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
int len = array.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
XophpArrayItm itm = array.Get_at_itm(i);
|
||||
|
||||
// get val as String
|
||||
String valStr = XophpObject_.ToStr(itm.Val());
|
||||
List<String> keyList = map.get(valStr);
|
||||
if (keyList == null) {
|
||||
keyList = new ArrayList<>();
|
||||
map.put(valStr, keyList);
|
||||
}
|
||||
keyList.add(itm.Key());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
private static void array_diff__remove_common_vals(Map<String, List<String>> lhsValMap, XophpArray lhs, XophpArray rhs) {
|
||||
int rhsLen = rhs.Len();
|
||||
for (int i = 0; i < rhsLen; i++) {
|
||||
XophpArrayItm rhsItm = rhs.Get_at_itm(i);
|
||||
String rhsVal = XophpObject_.ToStr(rhsItm.Val());
|
||||
List<String> lhsKeyList = lhsValMap.get(rhsVal);
|
||||
if (lhsKeyList != null) {
|
||||
for (String lhsKey : lhsKeyList) {
|
||||
lhs.Del_by(lhsKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// REF.PHP:https://www.php.net/manual/en/function.array-diff-key
|
||||
public static XophpArray array_diff_key(XophpArray array1, XophpArray array2, XophpArray... arrays) {
|
||||
// remove elements
|
||||
array_diff_key__remove_common_key(array1, array2);
|
||||
for (XophpArray array : arrays) {
|
||||
array_diff_key__remove_common_key(array1, array);
|
||||
}
|
||||
return array1;
|
||||
}
|
||||
private static void array_diff_key__remove_common_key(XophpArray lhs, XophpArray rhs) {
|
||||
int rhsLen = rhs.Len();
|
||||
for (int i = 0; i < rhsLen; i++) {
|
||||
XophpArrayItm rhsItm = rhs.Get_at_itm(i);
|
||||
String rhsKey = rhsItm.Key();
|
||||
if (lhs.Has(rhsKey)) {
|
||||
lhs.Del_by(rhsKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ import gplx.String_;
|
||||
import gplx.Type_;
|
||||
import gplx.core.brys.Bry_bfr_able;
|
||||
|
||||
public class XophpArrayItm implements Bry_bfr_able {
|
||||
XophpArrayItm(boolean keyIsInt, int keyAsInt, String key, Object val) {
|
||||
public class XophpArrayItm<T> implements Bry_bfr_able {
|
||||
XophpArrayItm(boolean keyIsInt, int keyAsInt, String key, T val) {
|
||||
this.keyIsInt = keyIsInt;
|
||||
this.keyAsInt = keyAsInt;
|
||||
this.key = key;
|
||||
@ -33,7 +33,7 @@ public class XophpArrayItm implements Bry_bfr_able {
|
||||
public boolean KeyIsInt() {return keyIsInt;} private final boolean keyIsInt;
|
||||
public int KeyAsInt() {return keyAsInt;} private final int keyAsInt;
|
||||
public String Key() {return key;} private final String key;
|
||||
public Object Val() {return val;} public void Val_(Object v) {this.val = v;} private Object val;
|
||||
public T Val() {return val;} public void Val_(T v) {this.val = v;} private T val;
|
||||
|
||||
public void To_bfr(Bry_bfr bfr) {
|
||||
bfr.Add_str_u8(key).Add_byte_eq();
|
||||
|
@ -96,4 +96,9 @@ public class XophpObject_ {
|
||||
|
||||
// equivalent to ??
|
||||
public static Object Coalesce(Object o, Object or) {return isset_obj(o) ? o : or;}
|
||||
|
||||
// equivalent to (string)o; see https://www.php.net/manual/en/function.array-diff.php
|
||||
public static String ToStr(Object o) {
|
||||
return o.toString();
|
||||
}
|
||||
}
|
||||
|
@ -15,15 +15,12 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.libs.services;
|
||||
|
||||
import gplx.xowa.mediawiki.XophpArray;
|
||||
import gplx.xowa.mediawiki.XophpArray;
|
||||
import gplx.xowa.mediawiki.XophpCallback;
|
||||
import gplx.xowa.mediawiki.XophpObject_;
|
||||
import gplx.xowa.mediawiki.XophpType_;
|
||||
/*
|
||||
XOTODO:
|
||||
* array_diff: https://www.php.net/manual/en/function.array-diff.php
|
||||
* array_diff_key: https://www.php.net/manual/en/function.array-diff-key
|
||||
* XomwAssert: /vendor/wikimedia/Assert/src
|
||||
*/
|
||||
// MW.SRC:1.33.1
|
||||
|
@ -389,6 +389,60 @@ public class XophpArrayStaticTest {
|
||||
XophpArray.reset(array);
|
||||
Gftest.Eq__str("step one", (String)XophpArray.current(array));
|
||||
}
|
||||
@Test public void array_diff() {
|
||||
// test To_str
|
||||
XophpArray<String> array1 = new XophpArray().Add("a", "0");
|
||||
XophpArray<Integer> arrayInt = new XophpArray().Add("a", 0);
|
||||
|
||||
fxt.Test__eq
|
||||
( new XophpArray<String>()
|
||||
, XophpArray.array_diff(array1, arrayInt)
|
||||
);
|
||||
|
||||
// test many
|
||||
XophpArray<String> array2, array3, array4;
|
||||
array1 = new XophpArray().Add_many("a", "b", "c", "d");
|
||||
array2 = new XophpArray().Add_many("a");
|
||||
array3 = new XophpArray().Add_many("c");
|
||||
array4 = new XophpArray().Add_many("d");
|
||||
|
||||
fxt.Test__eq
|
||||
( new XophpArray<String>().Add(1, "b")
|
||||
, XophpArray.array_diff(array1, array2, array3, array4)
|
||||
);
|
||||
|
||||
// PHP examples
|
||||
// Example #1 array_diff() example
|
||||
array1 = new XophpArray().Add("a", "green").Add_many("red", "blue", "red");
|
||||
array2 = new XophpArray().Add("b", "green").Add_many("yellow", "red");
|
||||
|
||||
fxt.Test__eq
|
||||
( new XophpArray<String>().Add(1, "blue")
|
||||
, XophpArray.array_diff(array1, array2)
|
||||
);
|
||||
}
|
||||
@Test public void array_diff_key() {
|
||||
// PHP examples
|
||||
// Example #1 array_diff_key() example
|
||||
XophpArray<Integer> array1, array2;
|
||||
array1 = new XophpArray<>().Add("blue", 1).Add("red", 2).Add("green", 3).Add("purple", 4);
|
||||
array2 = new XophpArray<>().Add("green", 5).Add("yellow", 7).Add("cyan", 8);
|
||||
|
||||
fxt.Test__eq
|
||||
( new XophpArray<String>().Add("blue", 1).Add("red", 2).Add("purple", 4)
|
||||
, XophpArray.array_diff_key(array1, array2)
|
||||
);
|
||||
|
||||
XophpArray<Integer> array3;
|
||||
array1 = new XophpArray<>().Add("blue", 1).Add("red", 2).Add("green", 3).Add("purple", 4);
|
||||
array2 = new XophpArray<>().Add("green", 5).Add("yellow", 7).Add("cyan", 8);
|
||||
array3 = new XophpArray<>().Add("blue", 6).Add("yellow", 7).Add("mauve", 8);
|
||||
|
||||
fxt.Test__eq
|
||||
( new XophpArray<String>().Add("red", 2).Add("purple", 4)
|
||||
, XophpArray.array_diff_key(array1, array2, array3)
|
||||
);
|
||||
}
|
||||
}
|
||||
class XophpArray_fxt {
|
||||
public XophpArray Make() {return new XophpArray();}
|
||||
|
Loading…
Reference in New Issue
Block a user