2020-05-01 13:01:40 +00:00
/ *
XOWA : the XOWA Offline Wiki Application
2020-05-07 12:58:15 +00:00
Copyright ( C ) 2012 - 2020 gnosygnu @gmail.com
2020-05-01 13:01:40 +00:00
XOWA is licensed under the terms of the General Public License ( GPL ) Version 3 ,
or alternatively under the terms of the Apache License Version 2 . 0 .
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case - by - case basis .
The terms of each license can be found in the source code repository :
GPLv3 License : https : //github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License : https : //github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
* /
2020-05-07 12:58:15 +00:00
package gplx.xowa.mediawiki ;
import gplx.Bool_ ;
import gplx.Bry_bfr ;
import gplx.Bry_bfr_ ;
import gplx.Char_ ;
import gplx.Int_ ;
2020-05-09 11:21:14 +00:00
import gplx.List_adp ;
import gplx.List_adp_ ;
2020-05-07 12:58:15 +00:00
import gplx.Object_ ;
import gplx.Ordered_hash ;
import gplx.Ordered_hash_ ;
import gplx.Type_ ;
2020-05-09 11:21:14 +00:00
import gplx.core.brys.Bry_bfr_able ;
import gplx.core.strings.String_bldr ;
import gplx.core.strings.String_bldr_ ;
2020-05-07 12:58:15 +00:00
import java.util.Iterator ;
// REF.PHP: https://www.php.net/manual/en/language.types.array.php
2020-05-09 11:21:14 +00:00
// also has static functions; REF.PHP: https://www.php.net/manual/en/ref.array.php
2020-05-07 12:58:15 +00:00
public class XophpArray < T > implements Bry_bfr_able , Iterable < T > {
private final Ordered_hash hash = Ordered_hash_ . New ( ) ;
private int newMemberIdx ;
public void Clear ( ) {
hash . Clear ( ) ;
newMemberIdx = 0 ;
internalPointerIndex = 0 ;
}
2020-04-03 10:39:35 +00:00
public int Len ( ) { return hash . Len ( ) ; }
2020-05-09 11:21:14 +00:00
public boolean Has_obj ( Object key ) { return Has ( Object_ . Xto_str_strict_or_null ( key ) ) ; }
public boolean Has ( String key ) {
return hash . Has ( key ) ;
2020-01-05 13:52:37 +00:00
}
2020-05-08 13:18:46 +00:00
public XophpArray Add ( T val ) {
2020-05-07 12:58:15 +00:00
int key = newMemberIdx + + ;
2020-05-09 11:21:14 +00:00
Set ( XophpArrayItm . NewInt ( key , val ) ) ;
2019-07-12 03:17:06 +00:00
return this ;
}
public XophpArray Add ( int key , Object val ) {
2020-05-07 12:58:15 +00:00
newMemberIdx = key + 1 ;
2020-05-09 11:21:14 +00:00
Set ( XophpArrayItm . NewInt ( key , val ) ) ;
2019-07-12 03:17:06 +00:00
return this ;
}
public XophpArray Add ( double key , Object val ) {
int key_as_int = ( int ) key ;
2020-05-07 12:58:15 +00:00
newMemberIdx = key_as_int + 1 ;
2020-05-09 11:21:14 +00:00
Set ( XophpArrayItm . NewInt ( key_as_int , val ) ) ;
2019-07-12 03:17:06 +00:00
return this ;
}
public XophpArray Add ( boolean key , Object val ) {
int key_as_int = key ? 1 : 0 ;
2020-05-07 12:58:15 +00:00
newMemberIdx = key_as_int + 1 ;
2020-05-09 11:21:14 +00:00
Set ( XophpArrayItm . NewInt ( key_as_int , val ) ) ;
2019-07-12 03:17:06 +00:00
return this ;
}
public XophpArray Add ( String key , Object val ) {
int key_as_int = Int_ . Parse_or ( key , Int_ . Min_value ) ;
if ( key_as_int = = Int_ . Min_value ) {
2020-05-09 11:21:14 +00:00
Set ( XophpArrayItm . NewStr ( key , val ) ) ;
2019-07-12 03:17:06 +00:00
}
else {
2020-05-09 11:21:14 +00:00
Set ( XophpArrayItm . NewInt ( key_as_int , val ) ) ;
2020-05-07 12:58:15 +00:00
newMemberIdx = key_as_int + 1 ;
2019-07-12 03:17:06 +00:00
}
return this ;
}
2020-01-04 09:14:36 +00:00
public XophpArray Add_as_key_and_val_many ( String . . . val ) {
for ( String itm : val ) {
Add ( itm , itm ) ;
}
return this ;
}
2020-05-08 13:18:46 +00:00
public XophpArray Add_many ( T . . . val ) {
for ( T itm : val ) {
2020-01-04 09:14:36 +00:00
Add ( itm ) ;
}
return this ;
}
2020-04-09 12:10:22 +00:00
public void Concat_str ( int i , String s ) {
this . Set ( i , this . Get_at_str ( i ) + s ) ;
}
public XophpArray Get_at_ary_or_null ( int i ) {
Object rv = Get_at ( i ) ;
return Type_ . Eq_by_obj ( rv , XophpArray . class ) ? ( XophpArray ) rv : null ;
}
2019-07-22 02:09:21 +00:00
public XophpArray Get_at_ary ( int i ) { return ( XophpArray ) Get_at ( i ) ; }
2019-12-07 13:13:52 +00:00
public int Get_at_int ( int i ) { return Int_ . Cast ( Get_at ( i ) ) ; }
2020-04-09 12:10:22 +00:00
public String Get_at_str ( int i ) { return ( String ) Get_at ( i ) ; }
2019-07-22 02:09:21 +00:00
public Object Get_at ( int i ) {
if ( i < 0 | | i > = hash . Len ( ) ) return null ;
XophpArrayItm itm = ( XophpArrayItm ) hash . Get_at ( i ) ;
return itm = = null ? null : itm . Val ( ) ;
2019-07-12 03:17:06 +00:00
}
2020-01-04 09:14:36 +00:00
public XophpArrayItm Get_at_itm ( int i ) {
if ( i < 0 | | i > = hash . Len ( ) ) return null ;
return ( XophpArrayItm ) hash . Get_at ( i ) ;
}
2019-07-22 02:09:21 +00:00
public Object Get_by_obj ( Object key ) { return Get_by ( Object_ . Xto_str_strict_or_null ( key ) ) ; }
public Object Get_by ( int key ) { return Get_by ( Int_ . To_str ( key ) ) ; }
2020-04-09 12:10:22 +00:00
public boolean Get_by_bool_or ( String key , boolean or ) { Object rv = this . Get_by ( key ) ; return rv = = null ? or : Bool_ . Cast ( rv ) ; }
2020-01-04 09:14:36 +00:00
public boolean Get_by_bool ( String key ) { return Bool_ . Cast ( this . Get_by ( key ) ) ; }
2020-04-09 12:10:22 +00:00
public int Get_by_int_or ( String key , int or ) { Object rv = this . Get_by ( key ) ; return rv = = null ? or : Int_ . Cast ( rv ) ; }
2019-12-07 13:13:52 +00:00
public int Get_by_int ( String key ) { return Int_ . Cast ( this . Get_by ( key ) ) ; }
2020-05-03 13:19:47 +00:00
public XophpArray Xet_by_ary ( String key ) {
XophpArrayItm itm = ( XophpArrayItm ) hash . Get_by ( key ) ;
if ( itm = = null ) {
XophpArray val = new XophpArray ( ) ;
this . Set ( key , val ) ;
return val ;
}
else {
return ( XophpArray ) itm . Val ( ) ;
}
}
2020-04-09 12:10:22 +00:00
public XophpArray Get_by_ary_or ( String key , XophpArray or ) { Object rv = this . Get_by ( key ) ; return rv = = null ? or : ( XophpArray ) rv ; }
2020-01-04 09:14:36 +00:00
public XophpArray Get_by_ary ( String key ) { return ( XophpArray ) this . Get_by ( key ) ; }
public String Get_by_str ( char key ) { return ( String ) this . Get_by ( Char_ . To_str ( key ) ) ; }
2020-04-09 12:10:22 +00:00
public String Get_by_str ( int key ) { return ( String ) this . Get_by ( Int_ . To_str ( key ) ) ; }
2020-01-04 09:14:36 +00:00
public String Get_by_str ( String key ) { return ( String ) this . Get_by ( key ) ; }
2020-05-08 13:18:46 +00:00
public T Get_by ( String key ) {
2019-07-12 03:17:06 +00:00
XophpArrayItm itm = ( XophpArrayItm ) hash . Get_by ( key ) ;
2020-05-08 13:18:46 +00:00
return itm = = null ? null : ( T ) itm . Val ( ) ;
2019-07-12 03:17:06 +00:00
}
public void Set ( int key , Object val ) {
2020-05-09 11:21:14 +00:00
this . Set ( XophpArrayItm . NewInt ( key , val ) ) ;
2019-07-12 03:17:06 +00:00
}
2020-01-04 09:14:36 +00:00
public void Set ( String key , Object val ) {
2020-05-09 11:21:14 +00:00
this . Set ( XophpArrayItm . NewStr ( key , val ) ) ;
2020-01-04 09:14:36 +00:00
}
2020-05-09 11:21:14 +00:00
private void Set ( XophpArrayItm itm ) {
String key = itm . Key ( ) ;
XophpArrayItm cur = ( XophpArrayItm ) hash . Get_by ( key ) ;
if ( cur = = null ) {
hash . Add ( key , itm ) ;
}
else {
cur . Val_ ( itm . Val ( ) ) ;
}
}
public void Del_at ( int i ) {
XophpArrayItm itm = ( XophpArrayItm ) hash . Get_at ( i ) ;
if ( itm ! = null ) {
hash . Del ( itm . Key ( ) ) ;
}
2019-07-12 03:17:06 +00:00
}
public XophpArrayItm [ ] To_ary ( ) {
return ( XophpArrayItm [ ] ) hash . To_ary ( XophpArrayItm . class ) ;
}
public String To_str ( ) {
Bry_bfr bfr = Bry_bfr_ . New ( ) ;
To_bfr ( bfr ) ;
return bfr . To_str_and_clear ( ) ;
}
public void To_bfr ( Bry_bfr bfr ) {
XophpArrayItm [ ] itms = To_ary ( ) ;
for ( XophpArrayItm itm : itms ) {
itm . To_bfr ( bfr ) ;
}
}
2019-12-07 13:13:52 +00:00
public void Itm_str_concat_end ( int idx , String v ) {
String itm = ( String ) this . Get_at ( idx ) ;
itm + = v ;
this . Set ( idx , itm ) ;
}
2020-05-04 12:29:37 +00:00
2020-01-04 09:14:36 +00:00
public XophpArray Clone ( ) {
XophpArray rv = new XophpArray ( ) ;
int len = hash . Len ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
XophpArrayItm itm = ( XophpArrayItm ) hash . Get_at ( i ) ;
rv . Add ( itm . Key ( ) , itm . Val ( ) ) ;
}
return rv ;
}
2020-04-09 12:10:22 +00:00
@Override public boolean equals ( Object obj ) {
if ( obj = = null ) return false ;
if ( ! Type_ . Eq_by_obj ( obj , XophpArray . class ) ) return false ;
XophpArray comp = ( XophpArray ) obj ;
// compare lens
int this_len = this . Len ( ) ;
int comp_len = comp . Len ( ) ;
if ( this_len ! = comp_len ) return false ;
// loop items
for ( int i = 0 ; i < this_len ; i + + ) {
XophpArrayItm this_itm = this . Get_at_itm ( i ) ;
XophpArrayItm comp_itm = comp . Get_at_itm ( i ) ;
if ( ! Object_ . Eq ( this_itm , comp_itm ) )
return false ;
}
return true ;
}
@Override public int hashCode ( ) {
int rv = 0 ;
int len = this . Len ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
XophpArrayItm itm = this . Get_at_itm ( i ) ;
rv = ( 31 * rv ) + itm . hashCode ( ) ;
}
return rv ;
}
2020-05-07 12:58:15 +00:00
@Override
public Iterator iterator ( ) {
return new XophpArrayIterator ( hash ) ;
}
class XophpArrayIterator implements Iterator < T > {
private final Ordered_hash hash ;
private int curIdx ;
private int len ;
public XophpArrayIterator ( Ordered_hash hash ) {
this . hash = hash ;
this . len = hash . Len ( ) ;
}
@Override
public boolean hasNext ( ) {
return curIdx < len ;
}
@Override
public T next ( ) {
return ( T ) hash . Get_at ( curIdx + + ) ;
}
@Override
public void remove ( ) {
throw new XophpRuntimeException ( " remove not supported " ) ;
}
2017-10-24 00:50:50 +00:00
}
2020-05-04 12:29:37 +00:00
2020-05-09 11:21:14 +00:00
// DEPRECATE:use XophpArray
public static boolean popBoolOrN ( List_adp list ) { return Bool_ . Cast ( List_adp_ . Pop_or ( list , false ) ) ; }
public static byte [ ] popBryOrNull ( List_adp list ) { return ( byte [ ] ) List_adp_ . Pop_or ( list , null ) ; }
public static String [ ] array_keys_str ( Ordered_hash array ) {
int len = array . Len ( ) ;
String [ ] rv = new String [ len ] ;
for ( int i = 0 ; i < len ; i + + ) {
rv [ i ] = ( String ) array . Get_at ( i ) ;
}
return rv ;
}
public static byte [ ] [ ] array_keys_bry ( Ordered_hash array ) {
int len = array . Len ( ) ;
byte [ ] [ ] rv = new byte [ len ] [ ] ;
for ( int i = 0 ; i < len ; i + + ) {
rv [ i ] = ( byte [ ] ) array . Get_at ( i ) ;
}
return rv ;
}
public static boolean array_key_exists ( int key , Ordered_hash array ) { return array . Has ( key ) ; }
public static boolean array_key_exists ( String key , Ordered_hash array ) { return array . Has ( key ) ; }
public static boolean array_key_exists ( byte [ ] key , Ordered_hash array ) { return array . Has ( key ) ; }
public static boolean empty ( Ordered_hash array ) {
return array . Len ( ) = = 0 ;
}
// **********
// * STATIC *
// **********
public static final XophpArray False = null ; // handles code like "if ($var === false)" where var is an Object;
public static XophpArray New ( Object . . . vals ) {
XophpArray rv = new XophpArray ( ) ;
for ( Object val : vals )
rv . Add ( val ) ;
return rv ;
}
public static boolean Eq_to_new ( XophpArray array ) { return array . hash . Count ( ) = = 0 ; } // same as "array === []"
public static boolean empty ( XophpArray array ) { return array . Len ( ) = = 0 ; }
public static int count ( XophpArray array ) { return array . Len ( ) ; }
public static boolean count_bool ( XophpArray array ) { return array . Len ( ) > 0 ; }
public static boolean isset ( XophpArray array , int key ) { return array . Get_at ( key ) ! = null ; }
public static boolean isset ( XophpArray array , String key ) { return array . Get_by ( key ) ! = null ; }
public static boolean is_array ( Object array ) { return XophpType_ . instance_of ( array , XophpArray . class ) ; }
public static void unset ( XophpArray array , String key ) { array . hash . Del ( key ) ; }
public static void unset ( XophpArray array , int key ) { array . hash . Del ( Int_ . To_str ( key ) ) ; }
public static void unset ( Ordered_hash array , Object key ) { array . Del ( key ) ; }
public static boolean array_key_exists ( String key , XophpArray array ) { return array . Has ( key ) ; }
public static boolean array_key_exists ( int key , XophpArray array ) { return array . Has ( Int_ . To_str ( key ) ) ; }
public static Object array_pop ( XophpArray array ) { // "array_pop"
int pos = array . Len ( ) - 1 ;
if ( pos < 0 ) return null ;
XophpArrayItm itm = ( XophpArrayItm ) array . hash . Get_at ( pos ) ;
array . Del_at ( pos ) ;
return itm . Val ( ) ;
}
public static Object end ( XophpArray array ) {
int len = array . Len ( ) ;
return len = = 0 ? null : ( ( XophpArrayItm ) array . hash . Get_at ( len - 1 ) ) . Val ( ) ;
}
// 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 ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
XophpArrayItm itm = array . Get_at_itm ( i ) ;
rv . Add ( i , itm . Val ( ) ) ;
}
return rv ;
}
2020-05-04 12:29:37 +00:00
// REF.PHP:https://www.php.net/manual/en/function.reset.php
private int internalPointerIndex = 0 ;
private Object internalPointerAdd ( int v ) {
internalPointerIndex + = v ;
return internalPointerGetOrNull ( ) ;
}
private Object internalPointerReset ( ) {
internalPointerIndex = 0 ;
return internalPointerGetOrNull ( ) ;
}
private Object internalPointerGetOrNull ( ) { return hash . Len ( ) = = 0 ? null : this . Get_at ( internalPointerIndex ) ; }
public static Object reset ( XophpArray array ) { return array . internalPointerReset ( ) ; }
public static Object current ( XophpArray array ) { return array . internalPointerGetOrNull ( ) ; }
public static Object next ( XophpArray array ) {
return array . internalPointerAdd ( 1 ) ;
}
2020-05-09 11:21:14 +00:00
// REF.PHP:https://www.php.net/manual/en/function.array-merge.php
public static XophpArray array_merge ( XophpArray . . . vals ) {
XophpArray rv = new XophpArray ( ) ;
for ( XophpArray ary : vals ) {
XophpArrayItm [ ] itms = ary . To_ary ( ) ;
for ( XophpArrayItm itm : itms ) {
array_itm_add ( rv , itm ) ;
}
}
return rv ;
2020-05-07 12:58:15 +00:00
}
2020-05-09 11:21:14 +00:00
// REF.PHP:https://www.php.net/manual/en/function.array-merge.php
// "If you want to append array elements from the second array to the first array while not overwriting the elements from the first array and not re-indexing, use the + array union operator:"
public static XophpArray array_add ( XophpArray lhs , XophpArray . . . vals ) {
for ( XophpArray ary : vals ) {
XophpArrayItm [ ] itms = ary . To_ary ( ) ;
for ( XophpArrayItm itm : itms ) {
if ( lhs . Has ( itm . Key ( ) ) ) {
continue ;
}
else {
lhs . Add ( itm . Key ( ) , itm . Val ( ) ) ;
}
}
}
return lhs ;
}
private static void array_itm_add ( XophpArray ary , XophpArrayItm itm ) {
if ( itm . KeyIsInt ( ) )
ary . Add ( itm . Val ( ) ) ;
else
ary . Add ( itm . Key ( ) , itm . Val ( ) ) ;
}
public static XophpArray array_splice ( XophpArray src , int bgn ) { return array_splice ( src , bgn , src . Len ( ) , null ) ; }
public static XophpArray array_splice ( XophpArray src , int bgn , int len ) { return array_splice ( src , bgn , len , null ) ; }
public static XophpArray array_splice ( XophpArray src , int bgn , int len , XophpArray repl ) {
// get itms before clearing it
int src_len = src . Len ( ) ;
XophpArrayItm [ ] itms = src . To_ary ( ) ;
src . Clear ( ) ;
// calc bgn
if ( bgn < 0 ) { // negative bgn should be adusted from src_len; EX: -1 means start at last item
bgn + = src_len ;
if ( bgn < 0 ) // large negative bgn should be capped at 0; EX: -99
bgn = 0 ;
}
else if ( bgn > src_len ) // large positive bgn should be capped at src_len; EX: 99
bgn = src_len ;
// add src from 0 to bgn
for ( int i = 0 ; i < bgn ; i + + ) {
array_itm_add ( src , itms [ i ] ) ;
}
// add repl
if ( repl ! = null ) {
XophpArrayItm [ ] repl_itms = repl . To_ary ( ) ;
for ( XophpArrayItm itm : repl_itms ) {
array_itm_add ( src , itm ) ;
}
}
// calc end
int end ;
if ( len < 0 ) { // negative len should be adjusted from src_len; EX: -1 means stop at last itm
end = src_len + len ;
if ( end < 0 ) // large_negative len should be capped at 0; EX: -99
end = 0 ;
}
else { // positive len should be added to bgn to find end
end = bgn + len ;
}
if ( end < bgn ) // end should never be less than bgn; EX: splice(1, -99)
end = bgn ;
else if ( end > src_len ) // end should not be more then end;
end = src_len ;
// add src from end to len
for ( int i = end ; i < src_len ; i + + ) {
array_itm_add ( src , itms [ i ] ) ;
}
// add del to rv
2020-05-07 12:58:15 +00:00
XophpArray rv = new XophpArray ( ) ;
2020-05-09 11:21:14 +00:00
for ( int i = bgn ; i < end ; i + + ) {
array_itm_add ( rv , itms [ i ] ) ;
}
return rv ;
}
// ( array $array , int $offset [, int $length = NULL [, boolean $preserve_keys = FALSE ]] ) :
public static XophpArray array_slice ( XophpArray array , int offset ) { return array_slice ( array , offset , array . Len ( ) ) ; }
public static XophpArray array_slice ( XophpArray array , int offset , int length ) {
XophpArray rv = new XophpArray ( ) ;
int end = offset + length ;
for ( int i = offset ; i < end ; i + + ) {
rv . Add ( array . Get_at ( i ) ) ;
}
return rv ;
}
public static XophpArray < String > array_keys ( XophpArray array ) {
XophpArray rv = XophpArray . New ( ) ;
int len = array . Len ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
XophpArrayItm itm = array . Get_at_itm ( i ) ;
rv . Add ( itm . Key ( ) ) ;
}
return rv ;
}
// REF.PHP:https://www.php.net/manual/en/function.array-map.php
public static XophpArray array_map ( XophpCallbackOwner callback_owner , String method , XophpArray array ) {
XophpArray rv = XophpArray . New ( ) ;
int len = array . Len ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
String itm = array . Get_at_str ( i ) ;
rv . Add ( ( String ) callback_owner . Call ( method , itm ) ) ;
}
return rv ;
}
// REF.PHP:https://www.php.net/manual/en/function.array-flip.php
public static XophpArray array_flip ( XophpArray array ) {
XophpArray rv = XophpArray . New ( ) ;
int len = array . Len ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
XophpArrayItm itm = array . Get_at_itm ( i ) ;
rv . Set ( Object_ . Xto_str_strict_or_null ( itm . Val ( ) ) , itm . Key ( ) ) ;
}
return rv ;
}
// REF.PHP:https://www.php.net/manual/en/function.implode.php
public static String implode ( String glue , XophpArray pieces ) {
String_bldr sb = String_bldr_ . new_ ( ) ;
int len = pieces . Len ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
if ( i ! = 0 ) sb . Add ( glue ) ;
sb . Add ( pieces . Get_at_str ( i ) ) ;
}
return sb . To_str_and_clear ( ) ;
}
// 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
Class < ? > needleType = null ;
if ( strict & & needle ! = null ) {
needleType = Type_ . Type_by_obj ( needle ) ;
}
// loop haystack to find match
int haystack_len = haystack . Len ( ) ;
for ( int i = 0 ; i < haystack_len ; i + + ) {
Object val = haystack . Get_at ( i ) ;
// if strict, compare types
if ( strict ) {
if ( needle ! = null & & val = = null ) {
return false ;
}
else if ( needle = = null & & val ! = null ) {
return false ;
}
else if ( needle ! = null & & val ! = null ) {
if ( ! Type_ . Eq_by_obj ( val , needleType ) ) {
return false ;
}
}
}
// compare objects
if ( Object_ . Eq ( needle , val ) ) {
return true ;
}
}
return false ;
}
// 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 ) {
return null ;
}
int len = array . Len ( ) ;
if ( len = = 0 ) {
return null ;
}
XophpArrayItm [ ] itms = array . To_ary ( ) ;
array . Clear ( ) ;
int idx = 0 ;
for ( int i = 1 ; i < len ; i + + ) {
XophpArrayItm itm = itms [ i ] ;
if ( itm . KeyIsInt ( ) ) {
array . Add ( idx + + , itm . Val ( ) ) ;
}
else {
array . Add ( itm . Key ( ) , itm . Val ( ) ) ;
}
}
return itms [ 0 ] . Val ( ) ;
}
// 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 ) ; }
public static XophpArray array_filter ( XophpArray array , XophpCallback callback , int flag ) {
XophpArray rv = new XophpArray ( ) ;
int len = array . Len ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
XophpArrayItm itm = array . Get_at_itm ( i ) ;
boolean filter = false ;
switch ( flag ) {
case ARRAY_FILTER_USE_VAL :
filter = Bool_ . Cast ( callback . Call ( itm . Val ( ) ) ) ;
break ;
case ARRAY_FILTER_USE_KEY :
filter = Bool_ . Cast ( callback . Call ( itm . Key ( ) ) ) ;
break ;
case ARRAY_FILTER_USE_BOTH :
filter = Bool_ . Cast ( callback . Call ( itm . Key ( ) , itm . Val ( ) ) ) ;
break ;
}
if ( filter )
rv . Add ( itm . Key ( ) , itm . Val ( ) ) ;
}
2020-05-07 12:58:15 +00:00
return rv ;
}
2020-05-09 11:21:14 +00:00
public static XophpCallback NULL_CALLBACK = new XophpCallback ( new XophpArray . XophpArrayFilterNullCallback ( ) , " " ) ;
static class XophpArrayFilterNullCallback implements XophpCallbackOwner {
public Object Call ( String method , Object . . . args ) {
if ( args . length ! = 1 ) throw new XophpRuntimeException ( " ArrayFilterNullCallback requires 1 arg " ) ;
Object arg = args [ 0 ] ;
return ! XophpObject_ . empty_obj ( arg ) ;
}
}
2017-10-24 00:50:50 +00:00
}