Extension talk:Arrays/archive

From mediawiki.org
Latest comment: 13 years ago by Kghbln in topic r83603 is broken

thanks

such a pragmatic extension thanks

Arraydefine

On your examples page you use something like

{{#arraydefine:a |1,2,3,2,1 |, |unique}}

which would create an array 1,2,3. But it's not documented here yet. Is this an permanent feature allready? Are there more values for this parameter? --Danwe 22:13, 25 February 2009 (UTC)Reply


Well, the feature has not yet been released because of some concerns on the design of function interface (users may want to set multiple values on the last parameter, e.g. make it unique, make it sort). would it be natural to use '&' to separate the values? - Lidingpku 14:04, 17 March 2009 (UTC)Reply

I don't know, I personal wouldn't use & but there could be reasons to do so. I like the last parameter to sort or unique in the same step and I already use this feature. --Danwe 20:41, 25 April 2009 (UTC)Reply
Ok, the option (unique, sort, and print) has been added in version 1.2.1 -- Lidingpku 15:39, 3 May 2009 (UTC)Reply

Arrayreset

I think #arrayreset is not very hepful in it's actual function. In most cases I have a template where I create a temporary array and I want to destory it there. But when you use {{#arrayreset:}} there, it will destroy ALL arrays, also these which were not defined in that template which are still needed in some cases. So perhaps it would be better if you could use that function #arrayreset alternatively like that: {{#arrayreset: key}} or even better: {{#arrayreset: key1 |key2 |key3 |key4...}}. Shure, you can also use {{#arraydefine:key1}} but I think it would be more pretty if you could use the #arrayreset function because you can see on first fiew where an array is going to be defined and where it will be destroyed. --Danwe 22:22, 25 February 2009 (UTC)Reply

ok, one option has been added to #arrayreset to support this idea. you can now use {{#arrayreset:key1,key2}} to unset a selection of arrays. - Lidingpku 14:28, 17 March 2009 (UTC)Reply

Bug in Arrayresets if no arrays are defined before

If you use #arrayreset before you have defined a array before, you will get a error on the top of the page (but only on the preview page). Sometimes I reset arrays on the beginning of a template because I need to reset some template internal arrays. If the template is used on the top of the page this creates an error on the preview page. --Danwe 14:57, 18 May 2009 (UTC)Reply

Arrayslice

I'm using arrayslice and am using 1 and 10 for the offset and length - then I am using arrayprint to post the 10 values in the new array. The extension is correctly posting 10 values; however, the array is starting with the second value of the array rather than the first. I have tried to post with an offset of zero and have even posted an arrayprint with an arrayslice with no length - the first value still doesn't show. Is this a bug, or am I doing something wrong?

Looks like they fixed that problem yesterday. Please youse the signature for the next time you add something to the talk page! --Danwe 20:39, 25 April 2009 (UTC)Reply

I found another bug in arrayslice:

{{#arraydefine: key |a,b,c}}
{{#arrayslice: key |key |3}} <!-- will return a,b,c instead of a void array -->
{{#arrayprint: key}}

This should return an void array because there are only 3 items inside the array. But instead of a void array the function returns the whole array. This is a problem with using variable parameters where you don't know before if the offset is bigger as the values. The bug appears for offsets >= arraysize. --Danwe 16:47, 28 April 2009 (UTC)Reply

it has been fixed in version 1.2.1, Lidingpku 15:55, 3 May 2009 (UTC)Reply

Arrayindex

If the arrayitem with the index doesn't exist or the index has an void entry, it should be possible to get an alternative value by adding this value as third parameter like: {{#arrayindex:key|2|''alternative value''}}. This would be the same as in VariablesExtension. --Danwe 22:57, 26 April 2009 (UTC)Reply

the option for "default" value has been added in version 1.2.1, Lidingpku 15:56, 3 May 2009 (UTC)Reply

#arrayexists ?

It would be great to have a function which discovers if an array exists or not. Actually I use #arraycount like this:

{{#ifeq: {{#arraysize:key}} | |doesn't exist |exists}}

because arraysize returns nothing if an array doesn't exist. But I am afraid of this behavoiur could change one day (for example 0 for not existing arrays or an error message...). I think the better way would be an #arrayexists function which will return true or something if the array exists and nothing if it doesn't. It could also work like {{#arrayexists |key |exists |doesn't exist}}.

By the way, I need to know if an array exists to cache the content of an array for a template so save some time. I do thant in many templates. --Danwe 19:26, 7 May 2009 (UTC)Reply

zero bug in arraydefine and arrayunique!

I was going to be crazy because I couldn't find a bug in my template. Finally I recorgnized this bug isn't in my template, it must be a ArrayExtension bug...

This bug is very strange. Whenever you have a zero "0" in your Array it happens. Arrayunique removes the "0" zero value! Even so does the unique command in Arraydefine. But that's not the only thing. When you define {{#arraydefine: test | 0 }} you get a void array with #arraysize = 0. BUT if you have {{#arraydefine: test | 0,1 }} the #arraysize is 2 and the "0" is in the array. But only as long as you don't run an #arrayunique on the array. This will remove the "0" again.

I don't know if there are any other functions which have the same effect on the zero. Arrayslice for example works well with zeros. Hope you can fix this bug soon. Actually I have some number arrays where zeros can appear as well. --Danwe 14:08, 17 May 2009 (UTC)Reply

it has been fixed in version 1.2.2, Lidingpku 15:35, 16 July 2009 (UTC)Reply
Looks like by fixing that bug, another bug came up in version 1.2.2 I think:
{{#arraydefine: ABC |0,a,b,,,,c,d,e,f,,g,h,,,, |,| unique }}{{#arrayprint: ABC }}
will print: 0, a, b, , c, d, e, f, g, h. The 0 works now thankfully but what's doing the void value there? The documentation for arrayunique says: This function converts an array (identified by 'key') into a set (no duplicated members, no empty element). But actually, there is an empty element left. Is this the new behavior or simply a bug (what I would suggest)? --Danwe 12:54, 17 December 2009 (UTC)Reply
A simple change in the code at line 392 (//if (!isset($v))) to the code if ( $v !== "" ) //preserve '0' but no '' values would do the trick. --Danwe 13:24, 17 December 2009 (UTC)Reply
Ok, it's fixed in version 1.2.3. Thanks! --Danwe 15:52, 18 December 2009 (UTC)Reply

New Functions

This extension looks really useful but it seems to be lacking a couple features, specifically functions to do push, pop, get and concat. The parserfunctions would look something like:

{{#arraypush:key|value|direction}} - if key doesn't exist, it is created; direction indicates beginning or end; so you can do FIFO and FILO
{{#arraypop:key|direction}} - pops the value from array and returns it, direction indicates beginning or end
{{#arrayget:key|position}} - returns the value at the indicated position, position could be positive or negative index.
{{#arrayconcat:newkey|leftkey|rightkey}}

-- BlindWanderer 16:00, 26 May 2009 (UTC)Reply

arraypush, arrayconcat, arraypop are replaced by arraymerge and arrayslice
arrayget is covered by arrayindex (expect the negative index is not supported)
Lidingpku 16:31, 16 July 2009 (UTC)Reply
One major omission seems to be to get the index value without doing a search.

example:

{{#arraydefine:x|1,2,3}}
{{#arraydefine:y|a,b,c}}
{{#arrayprint:x||@@@@| The number @@@@ corresponds to the same index value as {{#arrayprint:y|%%%%}}. }} //where %%%% would be the current index value of x
I often thought it would be nice to get the index in an arrayprint. A possible syntax for that could be {{#arrayprint:key||@@@@ %%%%|(%%%%) @@@@ {{#arrayindex:key2|%%%%}} }}. So the " " space would separate both patterns, the @@@@ which is the array value and %%%% as seccond which would be the index here. It's very unlikely that someone is using a pattern containing a " " so far. --Danwe 14:49, 12 February 2010 (UTC)Reply
I also needed this access to the index recently and made the necessary modification. There are only some small changes to the arrayprint-method needed. Only difference to the above proposal, i prefered ,(comma) as delimiter. Here the code, maybe it is usefull for somebody else or the maintainer wish to incorporate it in some later release.--132.180.63.80 08:52, 5 May 2010 (UTC)Reply
 function arrayprint( &$parser, $arrayid , $delimiter = ', ', $search='@@@@', $subject='@@@@', $frame=null) {
	$ret = $this->validate_array_by_arrayid($arrayid);
	if (true!==$ret) return $ret;
	$x = explode(',',$search);
	if ( count($x)>1 && strpos($subject,$index=$x[1])!==false ) { // we do val and ndx replace
		$search = $x[0];
		$qndx = true;
	} else  $qndx = false; 

	$values=array_values($this->mArrayExtension[$arrayid]); // make sure key runs 0..
	$rendered_values= array();
	foreach($values as $k => $v){
		$temp_result_value  = str_replace($search, $v, $subject); if ($qndx)
		$temp_result_value  = str_replace($index , $k, $temp_result_value);
		if (isset($frame)){
			$temp_result_value = $parser->preprocessToDom($temp_result_value,
			 $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0);
			$temp_result_value = trim($frame->expand($temp_result_value));
                }                  
		$rendered_values[] = $temp_result_value ;
	}
	return array(implode( $delimiter, $rendered_values) , 'noparse' => false, 'isHTML' => false);
 }
#arrayprinttemplate
One additional think I'd even appreciate more would be a real template call array print: {{#arrayprinttemplate:key |delimiter |template |additional parameters for template here and in the following |ones...}}.
Example:
{{#arrayprinttemplate:key |,<nowiki> </nowiki> |myTemplate |color=red |default=void entry}}
For this being able to work we need the template template:myTemplate:
( {{{_index}}} ) <span style="background-color:{{{color|}}}">{{#if:{{{_value}}} |{{{_value}}} |{{{default|}}}</span>
The parameters _index and _value would be two default parameters which ArrayExtension will deliver automatically. default and color are both parameters defined by the user in the #arrayprinttemplate call above. Other parameters ArrayExtension should deliver are _array (name of the array) and perhaps _isLastEntry and _isFirstEntry which contain a value (1) if true. --Danwe 14:49, 12 February 2010 (UTC)Reply

Arrayprint a list

Is it possible somehow to create a list with arrayprint? I tried:

{{#arraydefine: x |abc,defg,hijk,lmno}}
{{#arrayprint: x ||@@@@|*@@@@ }}

But that creates only one whole big list Entry and not four. The other three * don't end in list points, they stay as *

I also tried

{{#arrayprint: x ||@@@@|*@@@@ }}

Doesn't work as well. Any ideas? --Danwe 23:42, 13 October 2009 (UTC)Reply

here is a work around:
{{#arrayprint: x ||@@@@|<span></span>
*@@@@ }}
Lidingpku 19:56, 17 December 2009 (UTC)Reply
Good idea. Work's even better with a nowiki tag so you won't even have the ugly span in your HTML output:
{{#arrayprint: x ||@@@@|<nowiki/>
*@@@@ }}
--Danwe 04:17, 26 December 2009 (UTC)Reply

Some ugly warnings on page imports

I had to import many pages which are using ArrayExtension. I got hundrets of warnings, all because of preg_split() in line 162 of ArrayExtension.php because of Compilation failed: nothing to repeat at offset xxx and because of Invalid argument supplied for foreach() on line 463 of ArrayExtension.php --Danwe 12:32, 1 December 2009 (UTC)Reply

what deliminator did you use? can you show me link to the example?
Lidingpku 19:58, 17 December 2009 (UTC)Reply
Sorry I don't have the import.xml anymore. I imported more than hundred pages and some of the templates I imported are using ArrayExtension. What do you mean with deliminator? If you mean the deliminator for regex search: I use / for most and sometimes %. I will get you an example when the error occurs again. But it could also be that the error came up because a very bad bug in one of my templates which could lead to a regex in #arraysearch which is not valid. I fixed that bug now perhaps this was the source of the error in the first time... --Danwe 15:46, 18 December 2009 (UTC)Reply

#arraydefine bug with non escaped chars

If you use characters or words with chars which have a meaning in preg regex (. \ + * ? [ ^ ] $ ( ) { } = ! < > | :) you get a php warning and the #arraydefine doesn't work like expected. This could be solved easily by using the preg_quote php function in case the delimiter isn't a regex like expression.

You can also use the regex /^([\\/\\|%]).*\\1[imsu]*$/ to check whether the delimiter is a regex or not.

Example - this won't work: {{#arraydefine:x |abc<span></span>def<span></span>ghi<span></span>jkl<span></span>mno | <span></span> }} (I use <span></span> with Semantic MW as seperator in Attribute values which contain informations I validate in templates on other pages per query)

--Danwe 21:43, 30 December 2009 (UTC)Reply

This is working now. --Danwe 22:24, 26 January 2010 (UTC)Reply

modifiers for regex #arraydefine

Today I tried to create a #arraydefine which splits a string on its line breaks like that:

{{#arraydefine:test|a
b
c
d
e|/^/m}}

to split the sting on its line breakings. But it doesn't work because m and any other modifiers are ignored. Instead I have to use the much longer regex /(?:\r\n|\n|\r)/ to be sure that windows, mac and linux servers are compatible with the page. Especially the i modifier would be extremely helpful in many cases I can imagine. Enabling other characters as regex seperators than / would be nice as well. I often use % when I use many slashes inside my regex. --Danwe 22:42, 26 January 2010 (UTC)Reply

New Array from Arraysearch

It would be nice to have function like #arraysearch which allows to search an array but in addition to return all matches in a new array. For example {{#arraysearcharray:key |value |offset |limit}}. value would allow the same values as in #arraysearch (value can contain a regex or a normal values). offset would be the optional starting point to search from, limit a optional number of the maximum results for the new array.

At the moment I use #arraysearch in a loop until it returns no more hits. But this method is very expensive because it can end in many loops and parser function calls. Doing all of this with only one parser function would increase the performance.

Since there are already so much Array functions, perhaps it is time to think about a new name scheme for the function names. Functions which return a new array could be named like array_fromsearch, array_arraysearch, new_arraysearch or something else with a "_" to make it clear that this is a function to extract a new array with it. To be consistent the other functions which extract a new array should become a additional new function name as well. --Danwe 15:14, 12 February 2010 (UTC)Reply

I just released my own ArrayExtension release with a #arraysearcharray function inside. You can get it on User:Danwe/Extension:ArrayExtension.
Syntax: {{#arraysearcharray:arrayid_new |arrayid |needle |index |limit |transform}}
needle can be a search string which must match an array item to select it or it can be a regular expression. transform allows to add text which will replace the original array item values found by the search. The replacement allows to use $1, $2 and so on like in phps preg_replace if a regular expression is used as needle. --Danwe 06:07, 7 June 2010 (UTC)Reply

Bug in arrayintersect

I created a couple of arrays with arrayintersect. When I printed them out using arrayprint, they looked fine. But when I used arraysearch on them, they did not function. When I create what appears to be the same array with arraydefine and use the same arraysearch, the arraysearch works. Something invisible is wrong with the arrays created by arrayintersect, and it makes them unusable. --Deutne 22:44, 25 May 2010 (UTC)Reply

Yes, you are right. I can reproduce the problem:
{{#arraydefine:A| a,b,c,d,e,f,g, xx, yy, z |,|print=list}}

{{#arraydefine:B| 8,yy,12,3,5,3,xx,3,1,3 |,|print=list}}
{{#arrayintersect:X |A |B }}
'''{{#arraysearch:X |xx}}, {{#arraysearch:X |yy}}''' should be '''0, 1'''

{{#arrayprint: X}}
The arraysearch returns -1, -1 instead of 0, 1! This is a serious bug. --Danwe 05:11, 30 May 2010 (UTC)Reply
I spent some time fixing the problems. It was not only arrayintersect, also arraydiff was creating this problem. The problem was that those functions preserve the indexes of the items. This means items in the base array may be deleted but the following items keep their indexes. This results in an array with gaps. Some of the other array functions like arraysearch and arrayindex expecting an array without gaps.
I also fixed the bug #arraydefine bug with non escaped chars and did some minor code cleanup. You can get my release from User:Danwe/Extension:ArrayExtension. I will write a mail to Li Ding, perhaps I can help to improve ArrayFunctions in the future direct in the SVN repository. --Danwe 08:06, 30 May 2010 (UTC)Reply
Cool! Thanks! I sure hope your bug fixes and general improvements are incorporated into the official release soon. --Deutne 09:08, 3 June 2010 (UTC)Reply

Error in documentation for arraysearch

Also, the documentation for arraysearch says that it prints out index values or yes/no. It returns them, but it doesn't print them out as far as I can see. I prefer the returning to the printing, but the documentation should be updated. --Deutne 22:44, 25 May 2010 (UTC)Reply

Suggestion for arraymerge and arrayunion

It would be really nice if one could use these two functions on more than two arrays with one call. --Deutne 22:44, 25 May 2010 (UTC)Reply

Error in StubObject.php

When installing ArrayExtension on my wiki (details below) I get the following error...

Parameter 1 to Language::getMagic() expected to be a reference, value given in StubObject.php on line 58

Product Version MediaWiki 1.15.3 PHP 5.3.2 (cgi-fcgi) MySQL 5.0.32-Debian_7etch11-log

How to fix, what is the cause?

#arraydefine not working?

I'm working with the latest version of AarryExtension on a wiki and the #arraydefine parser simply doesn't work. That is, a call like

{{#arraydefine: testarray|1,2,3}}

outputs exactly that on the page. The other parsers appear to work just fine.

MediaWiki	1.15.1
PHP	5.3.2 (apache2handler)
MySQL	5.0.84sp1-enterprise-gpl-nt

I've tried disabling the extensions and that doesn't fix it, so I won't list them here.

you mean all other ArrayExtension functions seem to work fine, only #arraydefine doesn't work? If not try the other functions and report. If they don't work, there must be something wrong in your config. Also try to update to the most current version of ArrayExtension. --Danwe 07:56, 21 August 2010 (UTC)Reply

ArrayExtension and #ask, but the other way around

I'm trying to use ArrayExtension to take 3 arrays that are filled on a form, merge them together, and ultimately create an argument for #ask. For instance, I've got arrays

a = Mazda Ford GM
b = IBM Oracle McAfee
c = Vons Ralphs

I want to be able to form this:

 {{#ask:[[Category:Company]]
 [[Has Name:Mazda||Ford||GM||IBM||Oracle||McAfee||Vons||Ralphs]]
 ...
 }}

I've experimented with arraydefine/arraymerge/arrayprint, but I'm still not getting there. If a pro could offer some help, I'd appreciate it. Thanks. --Skew 02:21, 20 August 2010 (UTC)Reply

This will do it:
{{#arraydefine:allCompanies|{{#arraymap:{{{a|}}}|,|x|x}}}}
{{#arraydefine:tempkey2|{{#arraymap:{{{b|}}}|,|x|x}}}}
{{#arraymerge:tempkey3|allCompanies|tempkey2}}
{{#arraydefine:tempkey2|{{#arraymap:{{{c|}}}|,|x|x}}}}
{{#arraymerge:allCompanies|tempkey2|tempkey3}}


and then


[[Has Effort::{{#arrayprint:allCompanies|{{pipe}}{{pipe}}}}]]


with Template:pipe holding |


--72.130.157.217 03:46, 21 August 2010 (UTC) (Skew, forgot to log in)Reply
I wouldn't depend to much on this kind of #ask because when your array is to big this won't work anymore. As far as I remember there is a limitation for how many different possibilities you can set for the querry. I am not sure but perhaps it was the $smwgQMaxSize variable. Also I can't see any reason to use the arraymap function in this example. I would say the function is useless anyway if you have array functions activated. --Danwe 07:53, 21 August 2010 (UTC)Reply
You're right, and I did have to increase $smwgQMaxSize. As far the usefulness, it's a matter of user interface. In this example, all of the different companies belong to a Company category. Each includes an Industry parameter within the template. If a search is desired for common things between certain companies, this lets me list companies by industry on the form, rather than showing a single large list of unrelated companies. The consequence of that is that I end up with 3 arrays, and since I'm letting the user AND or OR the results, the OR case needs a single array so I can form the [[Has Company::a|b|m|n|y|z]] correctly. But with respect to the query itself, I'd much rather be able to do ([[Has Company::a|b]] OR [[Has Company::m|n]] OR [[Has Company::y|z]]), but the logic operator precedence rules with inline queries aren't that straight-forward for me yet (my actualy query is much more complex than this simple case in terms of ANDs and ORs). --Skew 16:56, 29 August 2010 (UTC)Reply
Instead of having very complex dynamic queries I often use a more generic querie and then use ArrayExtension to filter the informations I need.
The #arraysearcharray function is perfect for that. It enables to filter the array via regex and also to manipulate the entries at the same time.
The only thing which can be tricky is the output format of the #ask query. I have templates to change the query output format but I am currently working on a new query format which will enable to get the semantic data with user defined separation strings or even directly as array or hash table or some kind of mixed two dimensional collation. Until then you can check out my templates SMW-AskToArray and ?n-ary --Danwe 15:42, 30 August 2010 (UTC)Reply


In the future, it is much easier to do this, because that first method is grossly inefficient
for arrays a, b, c
{{#ask: [[Category:Company]][[Has Name:: {{#arraymap: a,b,c|,|arry|{{#arrayprint: arry| {{!}}{{!}} }}| {{!}}{{!}} }}]] }}
Given that you have a Template called ! which returns the pipe character '|'
If you have to merge them, then at least do this this line instead of the first 5 lines provided


{{#arraydefine: all |{{#arraymap: {{{a|}}},{{{b|}}},{{{c|}}} | , |ele|ele|}} }}


Yes, that arraymap is necessary, in the middle, or else there is a large potential for empty elements in the resulting array
Because of instances where you have "Make1, ,Make2,Make3," That first and last comma will, each, cause an empty element

Mathematical operations

Is there any way to perform mathematical operations on arrays, for example, adding two numerical arrays or multiplying them? Albmont 18:02, 23 August 2010 (UTC)Reply

You could use a loop with help of the loop extension or try to do it with arrayprint. --Danwe 10:55, 28 August 2010 (UTC)Reply

Missing SVN Version tags

The Extension doesnt have version tags (like in http://svn.wikimedia.org/viewvc/mediawiki/tags/extensions/SemanticMediaWiki/ ) in SVN ... it would be great for version management at installations to have these tags .. would it be possible to set a tag at the last release revision and provide tags in the future? --RScheiber 22:12, 14 September 2010 (UTC)Reply

Suggested additions to #arraysort

(deleted due to my own misunderstanding)

r83603 is broken

Hi, it is not possible to install this extension. Since I get a blanc page after including it, I suspect that some file is not found or at the place it should be. However, this is a wild guess. Cheers --[[kgh]] 20:20, 9 March 2011 (UTC)Reply

Thank you for fixing this with r83639 Jeroen. Cheers --[[kgh]] 16:28, 11 March 2011 (UTC)Reply