<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ar">
	<id>https://3rabica.org/index.php?action=history&amp;feed=atom&amp;title=%D9%88%D8%AD%D8%AF%D8%A9%3ALuaLinq</id>
	<title>وحدة:LuaLinq - تاريخ المراجعة</title>
	<link rel="self" type="application/atom+xml" href="https://3rabica.org/index.php?action=history&amp;feed=atom&amp;title=%D9%88%D8%AD%D8%AF%D8%A9%3ALuaLinq"/>
	<link rel="alternate" type="text/html" href="https://3rabica.org/index.php?title=%D9%88%D8%AD%D8%AF%D8%A9:LuaLinq&amp;action=history"/>
	<updated>2026-06-05T10:13:59Z</updated>
	<subtitle>تاريخ التعديل لهذه الصفحة في الويكي</subtitle>
	<generator>MediaWiki 1.43.7</generator>
	<entry>
		<id>https://3rabica.org/index.php?title=%D9%88%D8%AD%D8%AF%D8%A9:LuaLinq&amp;diff=1992&amp;oldid=prev</id>
		<title>عبد العزيز: أنشأ الصفحة ب&#039;-- LuaLinq - http://code.google.com/p/lualinq/ -- ------------------------------------------------------------------------ -- Copyright (c) 2012, Marco Mastropaolo (Xana...&#039;</title>
		<link rel="alternate" type="text/html" href="https://3rabica.org/index.php?title=%D9%88%D8%AD%D8%AF%D8%A9:LuaLinq&amp;diff=1992&amp;oldid=prev"/>
		<updated>2020-10-01T10:06:22Z</updated>

		<summary type="html">&lt;p&gt;أنشأ الصفحة ب&amp;#039;-- LuaLinq - http://code.google.com/p/lualinq/ -- ------------------------------------------------------------------------ -- Copyright (c) 2012, Marco Mastropaolo (Xana...&amp;#039;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;صفحة جديدة&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- LuaLinq - http://code.google.com/p/lualinq/&lt;br /&gt;
-- ------------------------------------------------------------------------&lt;br /&gt;
-- Copyright (c) 2012, Marco Mastropaolo (Xanathar)&lt;br /&gt;
-- All rights reserved.&lt;br /&gt;
-- &lt;br /&gt;
-- Redistribution and use in source and binary forms, with or without modification, &lt;br /&gt;
-- are permitted provided that the following conditions are met:&lt;br /&gt;
-- &lt;br /&gt;
--  o Redistributions of source code must retain the above copyright notice, &lt;br /&gt;
-- 	  this list of conditions and the following disclaimer.&lt;br /&gt;
--  o Redistributions in binary form must reproduce the above copyright notice, &lt;br /&gt;
-- 	  this list of conditions and the following disclaimer in the documentation &lt;br /&gt;
-- 	  and/or other materials provided with the distribution.&lt;br /&gt;
--  o Neither the name of Marco Mastropaolo nor the names of its contributors &lt;br /&gt;
-- 	  may be used to endorse or promote products derived from this software &lt;br /&gt;
-- 	  without specific prior written permission.&lt;br /&gt;
-- &lt;br /&gt;
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &amp;quot;AS IS&amp;quot; AND &lt;br /&gt;
-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED &lt;br /&gt;
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. &lt;br /&gt;
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, &lt;br /&gt;
-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, &lt;br /&gt;
-- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, &lt;br /&gt;
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF &lt;br /&gt;
-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE &lt;br /&gt;
-- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED &lt;br /&gt;
-- OF THE POSSIBILITY OF SUCH DAMAGE.&lt;br /&gt;
-- ------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
-- support lua 5.3&lt;br /&gt;
local unpack = table.unpack and table.unpack or unpack&lt;br /&gt;
&lt;br /&gt;
-- how much log information is printed: 3 =&amp;gt; verbose, 2 =&amp;gt; info, 1 =&amp;gt; only warning and errors, 0 =&amp;gt; only errors, -1 =&amp;gt; silent&lt;br /&gt;
local LOG_LEVEL = 1&lt;br /&gt;
&lt;br /&gt;
-- prefix for the printed logs&lt;br /&gt;
local LOG_PREFIX = &amp;quot;LuaLinq: &amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- ============================================================&lt;br /&gt;
-- DEBUG TRACER&lt;br /&gt;
-- ============================================================&lt;br /&gt;
&lt;br /&gt;
local LIB_VERSION_TEXT = &amp;quot;1.6.0&amp;quot;&lt;br /&gt;
local LIB_VERSION = 160&lt;br /&gt;
&lt;br /&gt;
local function setLogLevel(level)&lt;br /&gt;
	LOG_LEVEL = level;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function _log(level, prefix, text)&lt;br /&gt;
	if (level &amp;lt;= LOG_LEVEL) then&lt;br /&gt;
		print(prefix .. LOG_PREFIX .. text)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function logq(self, method)&lt;br /&gt;
	if (LOG_LEVEL &amp;gt;= 3) then&lt;br /&gt;
		logv(&amp;quot;after &amp;quot; .. method .. &amp;quot; =&amp;gt; &amp;quot; .. #self.m_Data .. &amp;quot; items : &amp;quot; .. _dumpData(self))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function _dumpData(self)&lt;br /&gt;
	local items = #self.m_Data&lt;br /&gt;
	local dumpdata = &amp;quot;q{ &amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	for i = 1, 3 do&lt;br /&gt;
		if (i &amp;lt;= items) then&lt;br /&gt;
			if (i ~= 1) then&lt;br /&gt;
				dumpdata = dumpdata .. &amp;quot;, &amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
			dumpdata = dumpdata .. tostring(self.m_Data[i])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (items &amp;gt; 3) then&lt;br /&gt;
		dumpdata = dumpdata .. &amp;quot;, ...&amp;quot; .. items .. &amp;quot; }&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		dumpdata = dumpdata .. &amp;quot; }&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return dumpdata&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function logv(txt)&lt;br /&gt;
	_log(3, &amp;quot;[..] &amp;quot;, txt)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function logi(txt)&lt;br /&gt;
	_log(2, &amp;quot;[ii] &amp;quot;, txt)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function logw(txt)&lt;br /&gt;
	_log(1, &amp;quot;[W?] &amp;quot;, txt)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function loge(txt)&lt;br /&gt;
	_log(0, &amp;quot;[E!] &amp;quot;, txt)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- ============================================================&lt;br /&gt;
-- CONSTRUCTOR&lt;br /&gt;
-- ============================================================&lt;br /&gt;
&lt;br /&gt;
local from&lt;br /&gt;
local fromArray&lt;br /&gt;
local fromArrayInstance&lt;br /&gt;
local fromDictionary&lt;br /&gt;
local fromIterator&lt;br /&gt;
local fromIteratorsArray&lt;br /&gt;
local fromNothing&lt;br /&gt;
local fromSet&lt;br /&gt;
local _all&lt;br /&gt;
local _any&lt;br /&gt;
local _average&lt;br /&gt;
local _concat&lt;br /&gt;
local _contains&lt;br /&gt;
local _count&lt;br /&gt;
local _distinct &lt;br /&gt;
local _dump&lt;br /&gt;
local _except&lt;br /&gt;
local _exceptby&lt;br /&gt;
local _first&lt;br /&gt;
local _foreach&lt;br /&gt;
local _foreach&lt;br /&gt;
local _intersection&lt;br /&gt;
local _intersectionby&lt;br /&gt;
local _last&lt;br /&gt;
local _map&lt;br /&gt;
local _max&lt;br /&gt;
local _min&lt;br /&gt;
local _random&lt;br /&gt;
local _select&lt;br /&gt;
local _selectMany&lt;br /&gt;
local _skip&lt;br /&gt;
local _sum&lt;br /&gt;
local _take&lt;br /&gt;
local _toArray&lt;br /&gt;
local _toDictionary&lt;br /&gt;
local _toIterator&lt;br /&gt;
local _toTuple&lt;br /&gt;
local _union&lt;br /&gt;
local _where&lt;br /&gt;
local _whereIndex&lt;br /&gt;
local _xmap&lt;br /&gt;
local _zip&lt;br /&gt;
&lt;br /&gt;
-- [private] Creates a linq data structure from an array without copying the data for efficiency&lt;br /&gt;
local function _new_lualinq(method, collection)&lt;br /&gt;
	local self = { }&lt;br /&gt;
	&lt;br /&gt;
	self.classid_71cd970f_a742_4316_938d_1998df001335 = 2&lt;br /&gt;
	&lt;br /&gt;
	self.m_Data = collection&lt;br /&gt;
	&lt;br /&gt;
	self.concat         = _concat&lt;br /&gt;
	self.select         = _select&lt;br /&gt;
	self.selectMany     = _selectMany&lt;br /&gt;
	self.where          = _where&lt;br /&gt;
	self.whereIndex     = _whereIndex&lt;br /&gt;
	self.take           = _take&lt;br /&gt;
	self.skip           = _skip&lt;br /&gt;
	self.zip            = _zip&lt;br /&gt;
	&lt;br /&gt;
	self.distinct       = _distinct &lt;br /&gt;
	self.union          = _union&lt;br /&gt;
	self.except         = _except&lt;br /&gt;
	self.intersection   = _intersection&lt;br /&gt;
	self.exceptby       = _exceptby&lt;br /&gt;
	self.intersectionby = _intersectionby&lt;br /&gt;
	self.exceptBy       = _exceptby&lt;br /&gt;
	self.intersectionBy = _intersectionby&lt;br /&gt;
	&lt;br /&gt;
	self.first          = _first&lt;br /&gt;
	self.last           = _last&lt;br /&gt;
	self.min            = _min&lt;br /&gt;
	self.max            = _max&lt;br /&gt;
	self.random         = _random&lt;br /&gt;
	&lt;br /&gt;
	self.any            = _any&lt;br /&gt;
	self.all            = _all&lt;br /&gt;
	self.contains       = _contains&lt;br /&gt;
	&lt;br /&gt;
	self.count          = _count&lt;br /&gt;
	self.sum            = _sum&lt;br /&gt;
	self.average        = _average&lt;br /&gt;
	&lt;br /&gt;
	self.dump           = _dump&lt;br /&gt;
	&lt;br /&gt;
	self.map            = _map&lt;br /&gt;
	self.foreach        = _foreach&lt;br /&gt;
	self.xmap           = _xmap&lt;br /&gt;
	&lt;br /&gt;
	self.toArray        = _toArray&lt;br /&gt;
	self.toDictionary   = _toDictionary&lt;br /&gt;
	self.toIterator     = _toIterator&lt;br /&gt;
	self.toTuple        = _toTuple&lt;br /&gt;
	&lt;br /&gt;
	-- shortcuts&lt;br /&gt;
	self.each           = _foreach&lt;br /&gt;
	self.intersect      = _intersection&lt;br /&gt;
	self.intersectby    = _intersectionby&lt;br /&gt;
	self.intersectBy    = _intersectionby&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	logq(self, &amp;quot;from&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	return self&lt;br /&gt;
end&lt;br /&gt;
-- ============================================================&lt;br /&gt;
-- GENERATORS&lt;br /&gt;
-- ============================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function p.main(auto)&lt;br /&gt;
    return from(auto)&lt;br /&gt;
end&lt;br /&gt;
-- Tries to autodetect input type and uses the appropriate from method&lt;br /&gt;
function from(auto)&lt;br /&gt;
	if (auto == nil) then&lt;br /&gt;
		return fromNothing()&lt;br /&gt;
	elseif (type(auto) == &amp;quot;function&amp;quot;) then&lt;br /&gt;
		return fromIterator(auto)&lt;br /&gt;
	elseif (type(auto) == &amp;quot;table&amp;quot;) then&lt;br /&gt;
		if (auto[&amp;quot;classid_71cd970f_a742_4316_938d_1998df001335&amp;quot;] ~= nil) then&lt;br /&gt;
			return auto&lt;br /&gt;
		elseif (auto[1] == nil) then&lt;br /&gt;
			return fromDictionary(auto)&lt;br /&gt;
		elseif (type(auto[1]) == &amp;quot;function&amp;quot;) then&lt;br /&gt;
			return fromIteratorsArray(auto)&lt;br /&gt;
		else&lt;br /&gt;
			return fromArrayInstance(auto)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return fromNothing()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Creates a linq data structure from an array without copying the data for efficiency&lt;br /&gt;
function fromArrayInstance(collection)&lt;br /&gt;
	return _new_lualinq(&amp;quot;fromArrayInstance&amp;quot;, collection)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Creates a linq data structure from an array copying the data first (so that changes in the original&lt;br /&gt;
-- table do not reflect here)&lt;br /&gt;
function fromArray(array)&lt;br /&gt;
	local collection = { }&lt;br /&gt;
	for k,v in ipairs(array) do&lt;br /&gt;
		table.insert(collection, v)&lt;br /&gt;
	end&lt;br /&gt;
	return _new_lualinq(&amp;quot;fromArray&amp;quot;, collection)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Creates a linq data structure from a dictionary (table with non-consecutive-integer keys)&lt;br /&gt;
function fromDictionary(dictionary)&lt;br /&gt;
	local collection = { }&lt;br /&gt;
	&lt;br /&gt;
	for k,v in pairs(dictionary) do&lt;br /&gt;
		local kvp = {}&lt;br /&gt;
		kvp.key = k&lt;br /&gt;
		kvp.value = v&lt;br /&gt;
		&lt;br /&gt;
		table.insert(collection, kvp)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;fromDictionary&amp;quot;, collection)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Creates a linq data structure from an iterator returning single items&lt;br /&gt;
function fromIterator(iterator)&lt;br /&gt;
	local collection = { }&lt;br /&gt;
	&lt;br /&gt;
	for s in iterator do&lt;br /&gt;
		table.insert(collection, s)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;fromIterator&amp;quot;, collection)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Creates a linq data structure from an array of iterators each returning single items&lt;br /&gt;
function fromIteratorsArray(iteratorArray)&lt;br /&gt;
	local collection = { }&lt;br /&gt;
&lt;br /&gt;
	for _, iterator in ipairs(iteratorArray) do&lt;br /&gt;
		for s in iterator do&lt;br /&gt;
			table.insert(collection, s)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;fromIteratorsArray&amp;quot;, collection)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Creates a linq data structure from a table of keys, values ignored&lt;br /&gt;
function fromSet(set)&lt;br /&gt;
	local collection = { }&lt;br /&gt;
&lt;br /&gt;
	for k,v in pairs(set) do&lt;br /&gt;
		table.insert(collection, k)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;fromIteratorsArray&amp;quot;, collection)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Creates an empty linq data structure&lt;br /&gt;
function fromNothing()&lt;br /&gt;
	return _new_lualinq(&amp;quot;fromNothing&amp;quot;, { } )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ============================================================&lt;br /&gt;
-- QUERY METHODS&lt;br /&gt;
-- ============================================================&lt;br /&gt;
&lt;br /&gt;
-- Concatenates two collections together&lt;br /&gt;
function _concat(self, otherlinq)&lt;br /&gt;
	local result = { }&lt;br /&gt;
&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		table.insert(result, value)&lt;br /&gt;
	end&lt;br /&gt;
	for idx, value in ipairs(otherlinq.m_Data) do&lt;br /&gt;
		table.insert(result, value)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;:concat&amp;quot;, result)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Replaces items with those returned by the selector function or properties with name selector&lt;br /&gt;
function _select(self, selector)&lt;br /&gt;
	local result = { }&lt;br /&gt;
&lt;br /&gt;
	if (type(selector) == &amp;quot;function&amp;quot;) then&lt;br /&gt;
		for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
			local newvalue = selector(value)&lt;br /&gt;
			if (newvalue ~= nil) then&lt;br /&gt;
				table.insert(result, newvalue)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	elseif (type(selector) == &amp;quot;string&amp;quot;) then&lt;br /&gt;
		for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
			local newvalue = value[selector]&lt;br /&gt;
			if (newvalue ~= nil) then&lt;br /&gt;
				table.insert(result, newvalue)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		loge(&amp;quot;select called with unknown predicate type&amp;quot;);&lt;br /&gt;
	end	&lt;br /&gt;
	return _new_lualinq(&amp;quot;:select&amp;quot;, result)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Replaces items with those contained in arrays returned by the selector function&lt;br /&gt;
function _selectMany(self, selector)&lt;br /&gt;
	local result = { }&lt;br /&gt;
&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		local newvalue = selector(value)&lt;br /&gt;
		if (newvalue ~= nil) then&lt;br /&gt;
			for ii, vv in ipairs(newvalue) do&lt;br /&gt;
				if (vv ~= nil) then&lt;br /&gt;
					table.insert(result, vv)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;:selectMany&amp;quot;, result)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Returns a linq data structure where only items for whose the predicate has returned true are included&lt;br /&gt;
function _where(self, predicate, refvalue, ...)&lt;br /&gt;
	local result = { }&lt;br /&gt;
&lt;br /&gt;
	if (type(predicate) == &amp;quot;function&amp;quot;) then&lt;br /&gt;
		for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
			if (predicate(value, refvalue, from({...}):toTuple())) then&lt;br /&gt;
				table.insert(result, value)&lt;br /&gt;
			end&lt;br /&gt;
		end	&lt;br /&gt;
	elseif (type(predicate) == &amp;quot;string&amp;quot;) then&lt;br /&gt;
		local refvals = {...}&lt;br /&gt;
		&lt;br /&gt;
		if (#refvals &amp;gt; 0) then&lt;br /&gt;
			table.insert(refvals, refvalue);&lt;br /&gt;
			return _intersectionby(self, predicate, refvals);&lt;br /&gt;
		elseif (refvalue ~= nil) then&lt;br /&gt;
			for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
				if (value[predicate] == refvalue) then&lt;br /&gt;
					table.insert(result, value)&lt;br /&gt;
				end&lt;br /&gt;
			end	&lt;br /&gt;
		else&lt;br /&gt;
			for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
				if (value[predicate] ~= nil) then&lt;br /&gt;
					table.insert(result, value)&lt;br /&gt;
				end&lt;br /&gt;
			end	&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		loge(&amp;quot;where called with unknown predicate type&amp;quot;);&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;:where&amp;quot;, result)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Returns a linq data structure where only items for whose the predicate has returned true are included, indexed version&lt;br /&gt;
function _whereIndex(self, predicate)&lt;br /&gt;
	local result = { }&lt;br /&gt;
&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		if (predicate(idx, value)) then&lt;br /&gt;
			table.insert(result, value)&lt;br /&gt;
		end&lt;br /&gt;
	end	&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;:whereIndex&amp;quot;, result)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Return a linq data structure with at most the first howmany elements&lt;br /&gt;
function _take(self, howmany)&lt;br /&gt;
	return self:whereIndex(function(i, v) return i &amp;lt;= howmany; end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Return a linq data structure skipping the first howmany elements&lt;br /&gt;
function _skip(self, howmany)&lt;br /&gt;
	return self:whereIndex(function(i, v) return i &amp;gt; howmany; end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Zips two collections together, using the specified join function&lt;br /&gt;
function _zip(self, otherlinq, joiner)&lt;br /&gt;
	otherlinq = from(otherlinq) &lt;br /&gt;
&lt;br /&gt;
	local thismax = #self.m_Data&lt;br /&gt;
	local thatmax = #otherlinq.m_Data&lt;br /&gt;
	local result = {}&lt;br /&gt;
	&lt;br /&gt;
	if (thatmax &amp;lt; thismax) then thismax = thatmax; end&lt;br /&gt;
	&lt;br /&gt;
	for i = 1, thismax do&lt;br /&gt;
		result[i] = joiner(self.m_Data[i], otherlinq.m_Data[i]);&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;:zip&amp;quot;, result)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns only distinct items, using an optional comparator&lt;br /&gt;
function _distinct(self, comparator)&lt;br /&gt;
	local result = {}&lt;br /&gt;
	comparator = comparator or function (v1, v2) return v1 == v2; end&lt;br /&gt;
	&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		local found = false&lt;br /&gt;
&lt;br /&gt;
		for _, value2 in ipairs(result) do&lt;br /&gt;
			if (comparator(value, value2)) then&lt;br /&gt;
				found = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
		if (not found) then&lt;br /&gt;
			table.insert(result, value)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return _new_lualinq(&amp;quot;:distinct&amp;quot;, result)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the union of two collections, using an optional comparator&lt;br /&gt;
function _union(self, other, comparator)&lt;br /&gt;
	return self:concat(from(other)):distinct(comparator)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the difference of two collections, using an optional comparator&lt;br /&gt;
function _except(self, other, comparator)&lt;br /&gt;
	other = from(other)&lt;br /&gt;
	return self:where(function (v) return not other:contains(v, comparator) end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the intersection of two collections, using an optional comparator&lt;br /&gt;
function _intersection(self, other, comparator)&lt;br /&gt;
	other = from(other)&lt;br /&gt;
	return self:where(function (v) return other:contains(v, comparator) end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the difference of two collections, using a property accessor&lt;br /&gt;
function _exceptby(self, property, other)&lt;br /&gt;
	other = from(other)&lt;br /&gt;
	return self:where(function (v) return not other:contains(v[property]) end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the intersection of two collections, using a property accessor&lt;br /&gt;
function _intersectionby(self, property, other)&lt;br /&gt;
	other = from(other)&lt;br /&gt;
	return self:where(function (v) return other:contains(v[property]) end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ============================================================&lt;br /&gt;
-- CONVERSION METHODS&lt;br /&gt;
-- ============================================================&lt;br /&gt;
&lt;br /&gt;
-- Converts the collection to an array&lt;br /&gt;
function _toIterator(self)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	local n = #self.m_Data&lt;br /&gt;
	return function ()&lt;br /&gt;
			i = i + 1&lt;br /&gt;
			if i &amp;lt;= n then return self.m_Data[i] end&lt;br /&gt;
		end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Converts the collection to an array&lt;br /&gt;
function _toArray(self)&lt;br /&gt;
	return self.m_Data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Converts the collection to a table using a selector functions which returns key and value for each item&lt;br /&gt;
function _toDictionary(self, keyValueSelector)&lt;br /&gt;
	local result = { }&lt;br /&gt;
&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		local key, value = keyValueSelector(value)&lt;br /&gt;
		if (key ~= nil) then&lt;br /&gt;
			result[key] = value&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Converts the lualinq struct to a tuple&lt;br /&gt;
function _toTuple(self)&lt;br /&gt;
	return unpack(self.m_Data)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- ============================================================&lt;br /&gt;
-- TERMINATING METHODS&lt;br /&gt;
-- ============================================================&lt;br /&gt;
&lt;br /&gt;
-- Return the first item or default if no items in the colelction&lt;br /&gt;
function _first(self, default)&lt;br /&gt;
	if (#self.m_Data &amp;gt; 0) then&lt;br /&gt;
		return self.m_Data[1]&lt;br /&gt;
	else&lt;br /&gt;
		return default&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Return the last item or default if no items in the colelction&lt;br /&gt;
function _last(self, default)&lt;br /&gt;
	if (#self.m_Data &amp;gt; 0) then&lt;br /&gt;
		return self.m_Data[#self.m_Data]&lt;br /&gt;
	else&lt;br /&gt;
		return default&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns true if any item satisfies the predicate. If predicate is null, it returns true if the collection has at least one item.&lt;br /&gt;
function _any(self, predicate)&lt;br /&gt;
	if (predicate == nil) then return #self.m_Data &amp;gt; 0; end&lt;br /&gt;
&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		if (predicate(value)) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns true if all items satisfy the predicate. If predicate is null, it returns true if the collection is empty.&lt;br /&gt;
function _all(self, predicate)&lt;br /&gt;
	if (predicate == nil) then return #self.m_Data == 0; end&lt;br /&gt;
&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		if (not predicate(value)) then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the number of items satisfying the predicate. If predicate is null, it returns the number of items in the collection.&lt;br /&gt;
function _count(self, predicate)&lt;br /&gt;
	if (predicate == nil) then return #self.m_Data; end&lt;br /&gt;
&lt;br /&gt;
	local result = 0&lt;br /&gt;
&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		if (predicate(value)) then&lt;br /&gt;
			result = result + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Prints debug data.&lt;br /&gt;
function _dump(self)&lt;br /&gt;
	print(_dumpData(self));&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns a random item in the collection, or default if no items are present&lt;br /&gt;
function _random(self, default)&lt;br /&gt;
	if (#self.m_Data == 0) then return default; end&lt;br /&gt;
	return self.m_Data[math.random(1, #self.m_Data)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns true if the collection contains the specified item&lt;br /&gt;
function _contains(self, item, comparator)&lt;br /&gt;
	comparator = comparator or function (v1, v2) return v1 == v2; end&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		if (comparator(value, item)) then return true; end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Calls the action for each item in the collection. Action takes 1 parameter: the item value.&lt;br /&gt;
-- If the action is a string, it calls that method with the additional parameters&lt;br /&gt;
function _foreach(self, action, ...)&lt;br /&gt;
	if (type(action) == &amp;quot;function&amp;quot;) then&lt;br /&gt;
		for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
			action(value, from({...}):toTuple())&lt;br /&gt;
		end&lt;br /&gt;
	elseif (type(action) == &amp;quot;string&amp;quot;) then&lt;br /&gt;
		for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
			value[action](value, from({...}):toTuple())&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		loge(&amp;quot;foreach called with unknown action type&amp;quot;);&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	return self&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Calls the accumulator for each item in the collection. Accumulator takes 2 parameters: value and the previous result of &lt;br /&gt;
-- the accumulator itself (firstvalue for the first call) and returns a new result.&lt;br /&gt;
function _map(self, accumulator, firstvalue)&lt;br /&gt;
	local result = firstvalue&lt;br /&gt;
&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		result = accumulator(value, result)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Calls the accumulator for each item in the collection. Accumulator takes 3 parameters: value, the previous result of &lt;br /&gt;
-- the accumulator itself (nil on first call) and the previous associated-result of the accumulator(firstvalue for the first call) &lt;br /&gt;
-- and returns a new result and a new associated-result.&lt;br /&gt;
function _xmap(self, accumulator, firstvalue)&lt;br /&gt;
	local result = nil&lt;br /&gt;
	local lastval = firstvalue&lt;br /&gt;
&lt;br /&gt;
	for idx, value in ipairs(self.m_Data) do&lt;br /&gt;
		result, lastval = accumulator(value, result, lastval)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the max of a collection. Selector is called with values and should return a number. Can be nil if collection is of numbers.&lt;br /&gt;
function _max(self, selector)&lt;br /&gt;
 	if (selector == nil) then &lt;br /&gt;
		selector = function(n) return n; end&lt;br /&gt;
	end&lt;br /&gt;
  	return self:xmap(function(v, r, l) local res = selector(v); if (l == nil or res &amp;gt; l) then return v, res; else return r, l; end; end, nil)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the min of a collection. Selector is called with values and should return a number. Can be nil if collection is of numbers.&lt;br /&gt;
function _min(self, selector)&lt;br /&gt;
	if (selector == nil) then &lt;br /&gt;
		selector = function(n) return n; end&lt;br /&gt;
	end&lt;br /&gt;
  	return self:xmap(function(v, r, l) local res = selector(v); if (l == nil or res &amp;lt; l) then return v, res; else return r, l; end; end, nil)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the sum of a collection. Selector is called with values and should return a number. Can be nil if collection is of numbers.&lt;br /&gt;
function _sum(self, selector)&lt;br /&gt;
	if (selector == nil) then &lt;br /&gt;
		selector = function(n) return n; end&lt;br /&gt;
	end&lt;br /&gt;
	return self:map(function(n, r) r = r + selector(n); return r; end, 0)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the average of a collection. Selector is called with values and should return a number. Can be nil if collection is of numbers.&lt;br /&gt;
function _average(self, selector)&lt;br /&gt;
	local count = self:count()&lt;br /&gt;
	if (count &amp;gt; 0) then&lt;br /&gt;
		return self:sum(selector) / count&lt;br /&gt;
	else&lt;br /&gt;
		return 0&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>عبد العزيز</name></author>
	</entry>
</feed>