数组操纵类   
               添加时间:2013-7-3 点击量: 
 
              
class ArrayHelper{
    
    /
      从数组中删除空白的元素(包含只有空白字符的元素)
     
      用法:
      @code php
      ¥arr = array(, test,    );
      ArrayHelper::removeEmpty(¥arr);
     
      dump(¥arr);
        // 输出成果中将只有 test
      @endcode
     
      @param array ¥arr 要处理惩罚的数组
      @param boolean ¥trim 是否对数组元素调用 trim 函数
     /
    static function removeEmpty(& ¥arr, ¥trim = TRUE)
    {
        foreach (¥arr as ¥key => ¥value)
        {
            if (is_array(¥value))
            {
                self::removeEmpty(¥arr[¥key]);
            }
            else
            {
                ¥value = trim(¥value);
                if (¥value == )
                {
                    unset(¥arr[¥key]);
                }
                elseif (¥trim)
                {
                    ¥arr[¥key] = ¥value;
                }
            }
        }
    }
    
    /
      从一个二维数组中返回指定键的所有值
     
      用法:
      @code php
      ¥rows = array(
          array(id => 1, value => 1-1),
          array(id => 2, value => 2-1),
      );
      ¥values = ArrayHelper::getCols(¥rows, value);
     
      dump(¥values);
        // 输出成果为
        // array(
        //   1-1,
        //   2-1,
        // )
      @endcode
     
      @param array ¥arr 数据源
      @param string ¥col 要查询的键
     
      @return array 包含指定键所有值的数组
     /
    static function getCols(¥arr, ¥col)
    {
        ¥ret = array();
        foreach (¥arr as ¥row)
        {
            if (isset(¥row[¥col])) {
                ¥ret[] = ¥row[¥col];
            }
        }
        return ¥ret;
    }
    
    /
      将一个二维数组转换为 HashMap,并返回成果
     
      用法1:
      @code php
      ¥rows = array(
          array(id => 1, value => 1-1),
          array(id => 2, value => 2-1),
      );
      ¥hashmap = ArrayHelper::toHashmap(¥rows, id, value);
     
      dump(¥hashmap);
        // 输出成果为
        // array(
        //   1 => 1-1,
        //   2 => 2-1,
        // )
      @endcode
     
      若是省略 ¥valueField 参数,则转换成果每一项为包含该项所稀有据的数组。
     
      用法2:
      @code php
      ¥rows = array(
          array(id => 1, value => 1-1),
          array(id => 2, value => 2-1),
      );
      ¥hashmap = ArrayHelper::toHashmap(¥rows, id);
     
      dump(¥hashmap);
        // 输出成果为
        // array(
        //   1 => array(id => 1, value => 1-1),
        //   2 => array(id => 2, value => 2-1),
        // )
      @endcode
     
      @param array ¥arr 数据源
      @param string ¥keyField 遵守什么键的值进行转换
      @param string ¥valueField 对应的键值
     
      @return array 转换后的 HashMap 样式数组
     /
    static function toHashmap(¥arr, ¥keyField, ¥valueField = NULL)
    {
        ¥ret = array();
        if (¥valueField)
        {
            foreach (¥arr as ¥row)
            {
                ¥ret[¥row[¥keyField]] = ¥row[¥valueField];
            }
        }
        else
        {
            foreach (¥arr as ¥row)
            {
                ¥ret[¥row[¥keyField]] = ¥row;
            }
        }
        return ¥ret;
    }
    
    /
      将一个二维数组遵守指定字段的值分组
     
      用法:
      @code php
      ¥rows = array(
          array(id => 1, value => 1-1, parent => 1),
          array(id => 2, value => 2-1, parent => 1),
          array(id => 3, value => 3-1, parent => 1),
          array(id => 4, value => 4-1, parent => 2),
          array(id => 5, value => 5-1, parent => 2),
          array(id => 6, value => 6-1, parent => 3),
      );
      ¥values = ArrayHelper::groupBy(¥rows, parent);
     
      dump(¥values);
        // 遵守 parent 分组的输出成果为
        // array(
        //   1 => array(
        //        array(id => 1, value => 1-1, parent => 1),
        //        array(id => 2, value => 2-1, parent => 1),
        //        array(id => 3, value => 3-1, parent => 1),
        //   ),
        //   2 => array(
        //        array(id => 4, value => 4-1, parent => 2),
        //        array(id => 5, value => 5-1, parent => 2),
        //   ),
        //   3 => array(
        //        array(id => 6, value => 6-1, parent => 3),
        //   ),
        // )
      @endcode
     
      @param array ¥arr 数据源
      @param string ¥keyField 作为分组根据的键名
     
      @return array 分组后的成果
     /
    static function groupBy(¥arr, ¥keyField)
    {
        ¥ret = array();
        foreach (¥arr as ¥row)
        {
            ¥key = ¥row[¥keyField];
            ¥ret[¥key][] = ¥row;
        }
        return ¥ret;
    }
    
    /
      将一个平面的二维数组遵守指定的字段转换为树状布局
     
      用法:
      @code php
      ¥rows = array(
          array(id => 1, value => 1-1, parent => 0),
          array(id => 2, value => 2-1, parent => 0),
          array(id => 3, value => 3-1, parent => 0),
     
          array(id => 7, value => 2-1-1, parent => 2),
          array(id => 8, value => 2-1-2, parent => 2),
          array(id => 9, value => 3-1-1, parent => 3),
          array(id => 10, value => 3-1-1-1, parent => 9),
      );
     
      ¥tree = ArrayHelper::tree(¥rows, id, parent, nodes);
     
      dump(¥tree);
        // 输出成果为:
        // array(
        //   array(id => 1, ..., nodes => array()),
        //   array(id => 2, ..., nodes => array(
        //        array(..., parent => 2, nodes => array()),
        //        array(..., parent => 2, nodes => array()),
        //   ),
        //   array(id => 3, ..., nodes => array(
        //        array(id => 9, ..., parent => 3, nodes => array(
        //             array(..., , parent => 9, nodes => array(),
        //        ),
        //   ),
        // )
      @endcode
     
      若是要获得随便率性节点为根的子树,可以应用 ¥refs 参数:
      @code php
      ¥refs = null;
      ¥tree = ArrayHelper::tree(¥rows, id, parent, nodes, ¥refs);
     
      // 输出 id 为 3 的节点及其所有子节点
      ¥id = 3;
      dump(¥refs[¥id]);
      @endcode
     
      @param array ¥arr 数据源
      @param string ¥keyNodeId 节点ID字段名
      @param string ¥keyParentId 节点父ID字段名
      @param string ¥keyChildrens 保存子节点的字段名
      @param boolean ¥refs 是否在返回成果中包含节点引用
     
      return array 树形布局的数组
     /
    static function toTree(¥arr, ¥keyNodeId, ¥keyParentId = parent_id, ¥keyChildrens = childrens, & ¥refs = NULL)
    {
        ¥refs = array();
        foreach (¥arr as ¥offset => ¥row)
        {
            ¥arr[¥offset][¥keyChildrens] = array();
            ¥refs[¥row[¥keyNodeId]] =& ¥arr[¥offset];
        }
    
        ¥tree = array();
        foreach (¥arr as ¥offset => ¥row)
        {
            ¥parentId = ¥row[¥keyParentId];
            if (¥parentId)
            {
                if (!isset(¥refs[¥parentId]))
                {
                    ¥tree[] =& ¥arr[¥offset];
                    continue;
                }
                ¥parent =& ¥refs[¥parentId];
                ¥parent[¥keyChildrens][] =& ¥arr[¥offset];
            }
            else
            {
                ¥tree[] =& ¥arr[¥offset];
            }
        }
        return ¥tree;
    }
    
    /
      将树形数组展开为平面的数组
     
      这个办法是 tree() 办法的逆向操纵。
     
      @param array ¥tree 树形数组
      @param string ¥keyChildrens 包含子节点的键名
     
      @return array 展开后的数组
     /
    static function treeToArray(¥tree, ¥keyChildrens = childrens)
    {
        ¥ret = array();
        if (isset(¥tree[¥keyChildrens]) && is_array(¥tree[¥keyChildrens]))
        {
            foreach (¥tree[¥keyChildrens] as ¥child)
            {
                ¥ret = array_merge(¥ret, self::treeToArray(¥child, ¥keyChildrens));
            }
            unset(¥node[¥keyChildrens]);
            ¥ret[] = ¥tree;
        }
        else
        {
            ¥ret[] = ¥tree;
        }
        return ¥ret;
    }
    
    /
      按照指定的键对数组排序
     
      用法:
      @code php
      ¥rows = array(
          array(id => 1, value => 1-1, parent => 1),
          array(id => 2, value => 2-1, parent => 1),
          array(id => 3, value => 3-1, parent => 1),
          array(id => 4, value => 4-1, parent => 2),
          array(id => 5, value => 5-1, parent => 2),
          array(id => 6, value => 6-1, parent => 3),
      );
     
      ¥rows = ArrayHelper::sortByCol(¥rows, id, SORT_DESC);
      dump(¥rows);
      // 输出成果为:
      // array(
      //   array(id => 6, value => 6-1, parent => 3),
      //   array(id => 5, value => 5-1, parent => 2),
      //   array(id => 4, value => 4-1, parent => 2),
      //   array(id => 3, value => 3-1, parent => 1),
      //   array(id => 2, value => 2-1, parent => 1),
      //   array(id => 1, value => 1-1, parent => 1),
      // )
      @endcode
     
      @param array ¥array 要排序的数组
      @param string ¥keyname 排序的键
      @param int ¥dir 排序标的目标
     
      @return array 排序后的数组
     /
    static function sortByCol(¥array, ¥keyname, ¥dir = SORT_ASC)
    {
        return self::sortByMultiCols(¥array, array(¥keyname => ¥dir));
    }
    
    /
      将一个二维数组遵守多个列进行排序,类似 SQL 语句中的 ORDER BY
     
      用法:
      @code php
      ¥rows = ArrayHelper::sortByMultiCols(¥rows, array(
          parent => SORT_ASC,
          name => SORT_DESC,
      ));
      @endcode
     
      @param array ¥rowset 要排序的数组
      @param array ¥args 排序的键
     
      @return array 排序后的数组
     /
    static function sortByMultiCols(¥rowset, ¥args)
    {
        ¥sortArray = array();
        ¥sortRule = ;
        foreach (¥args as ¥sortField => ¥sortDir)
        {
            foreach (¥rowset as ¥offset => ¥row)
            {
                ¥sortArray[¥sortField][¥offset] = ¥row[¥sortField];
            }
            ¥sortRule .= ¥sortArray[\ . ¥sortField . \],  . ¥sortDir . , ;
        }
        if (empty(¥sortArray) || empty(¥sortRule)) {
            return ¥rowset;
        }
        eval(array_multisort( . ¥sortRule . ¥rowset););
        return ¥rowset;
    }
    
    
}
无论对感情还是对生活,“只要甜不要苦”都是任性而孩子气的,因为我们也不完美,我们也会伤害人。正因为我们都不完美,也因为生活从不是事事如意,所以对这些“瑕疵”的收纳才让我们对生活、对他人的爱变得日益真实而具体。—— 汪冰《世界再亏欠你,也要敢于拥抱幸福》
                     
                  
     
  
 
    
    
class ArrayHelper{
/
从数组中删除空白的元素(包含只有空白字符的元素)
用法:
@code php
¥arr = array(, test, );
ArrayHelper::removeEmpty(¥arr);
dump(¥arr);
// 输出成果中将只有 test
@endcode
@param array ¥arr 要处理惩罚的数组
@param boolean ¥trim 是否对数组元素调用 trim 函数
/
static function removeEmpty(& ¥arr, ¥trim = TRUE)
{
foreach (¥arr as ¥key => ¥value)
{
if (is_array(¥value))
{
self::removeEmpty(¥arr[¥key]);
}
else
{
¥value = trim(¥value);
if (¥value == )
{
unset(¥arr[¥key]);
}
elseif (¥trim)
{
¥arr[¥key] = ¥value;
}
}
}
}
/
从一个二维数组中返回指定键的所有值
用法:
@code php
¥rows = array(
array(id => 1, value => 1-1),
array(id => 2, value => 2-1),
);
¥values = ArrayHelper::getCols(¥rows, value);
dump(¥values);
// 输出成果为
// array(
// 1-1,
// 2-1,
// )
@endcode
@param array ¥arr 数据源
@param string ¥col 要查询的键
@return array 包含指定键所有值的数组
/
static function getCols(¥arr, ¥col)
{
¥ret = array();
foreach (¥arr as ¥row)
{
if (isset(¥row[¥col])) {
¥ret[] = ¥row[¥col];
}
}
return ¥ret;
}
/
将一个二维数组转换为 HashMap,并返回成果
用法1:
@code php
¥rows = array(
array(id => 1, value => 1-1),
array(id => 2, value => 2-1),
);
¥hashmap = ArrayHelper::toHashmap(¥rows, id, value);
dump(¥hashmap);
// 输出成果为
// array(
// 1 => 1-1,
// 2 => 2-1,
// )
@endcode
若是省略 ¥valueField 参数,则转换成果每一项为包含该项所稀有据的数组。
用法2:
@code php
¥rows = array(
array(id => 1, value => 1-1),
array(id => 2, value => 2-1),
);
¥hashmap = ArrayHelper::toHashmap(¥rows, id);
dump(¥hashmap);
// 输出成果为
// array(
// 1 => array(id => 1, value => 1-1),
// 2 => array(id => 2, value => 2-1),
// )
@endcode
@param array ¥arr 数据源
@param string ¥keyField 遵守什么键的值进行转换
@param string ¥valueField 对应的键值
@return array 转换后的 HashMap 样式数组
/
static function toHashmap(¥arr, ¥keyField, ¥valueField = NULL)
{
¥ret = array();
if (¥valueField)
{
foreach (¥arr as ¥row)
{
¥ret[¥row[¥keyField]] = ¥row[¥valueField];
}
}
else
{
foreach (¥arr as ¥row)
{
¥ret[¥row[¥keyField]] = ¥row;
}
}
return ¥ret;
}
/
将一个二维数组遵守指定字段的值分组
用法:
@code php
¥rows = array(
array(id => 1, value => 1-1, parent => 1),
array(id => 2, value => 2-1, parent => 1),
array(id => 3, value => 3-1, parent => 1),
array(id => 4, value => 4-1, parent => 2),
array(id => 5, value => 5-1, parent => 2),
array(id => 6, value => 6-1, parent => 3),
);
¥values = ArrayHelper::groupBy(¥rows, parent);
dump(¥values);
// 遵守 parent 分组的输出成果为
// array(
// 1 => array(
// array(id => 1, value => 1-1, parent => 1),
// array(id => 2, value => 2-1, parent => 1),
// array(id => 3, value => 3-1, parent => 1),
// ),
// 2 => array(
// array(id => 4, value => 4-1, parent => 2),
// array(id => 5, value => 5-1, parent => 2),
// ),
// 3 => array(
// array(id => 6, value => 6-1, parent => 3),
// ),
// )
@endcode
@param array ¥arr 数据源
@param string ¥keyField 作为分组根据的键名
@return array 分组后的成果
/
static function groupBy(¥arr, ¥keyField)
{
¥ret = array();
foreach (¥arr as ¥row)
{
¥key = ¥row[¥keyField];
¥ret[¥key][] = ¥row;
}
return ¥ret;
}
/
将一个平面的二维数组遵守指定的字段转换为树状布局
用法:
@code php
¥rows = array(
array(id => 1, value => 1-1, parent => 0),
array(id => 2, value => 2-1, parent => 0),
array(id => 3, value => 3-1, parent => 0),
array(id => 7, value => 2-1-1, parent => 2),
array(id => 8, value => 2-1-2, parent => 2),
array(id => 9, value => 3-1-1, parent => 3),
array(id => 10, value => 3-1-1-1, parent => 9),
);
¥tree = ArrayHelper::tree(¥rows, id, parent, nodes);
dump(¥tree);
// 输出成果为:
// array(
// array(id => 1, ..., nodes => array()),
// array(id => 2, ..., nodes => array(
// array(..., parent => 2, nodes => array()),
// array(..., parent => 2, nodes => array()),
// ),
// array(id => 3, ..., nodes => array(
// array(id => 9, ..., parent => 3, nodes => array(
// array(..., , parent => 9, nodes => array(),
// ),
// ),
// )
@endcode
若是要获得随便率性节点为根的子树,可以应用 ¥refs 参数:
@code php
¥refs = null;
¥tree = ArrayHelper::tree(¥rows, id, parent, nodes, ¥refs);
// 输出 id 为 3 的节点及其所有子节点
¥id = 3;
dump(¥refs[¥id]);
@endcode
@param array ¥arr 数据源
@param string ¥keyNodeId 节点ID字段名
@param string ¥keyParentId 节点父ID字段名
@param string ¥keyChildrens 保存子节点的字段名
@param boolean ¥refs 是否在返回成果中包含节点引用
return array 树形布局的数组
/
static function toTree(¥arr, ¥keyNodeId, ¥keyParentId = parent_id, ¥keyChildrens = childrens, & ¥refs = NULL)
{
¥refs = array();
foreach (¥arr as ¥offset => ¥row)
{
¥arr[¥offset][¥keyChildrens] = array();
¥refs[¥row[¥keyNodeId]] =& ¥arr[¥offset];
}
¥tree = array();
foreach (¥arr as ¥offset => ¥row)
{
¥parentId = ¥row[¥keyParentId];
if (¥parentId)
{
if (!isset(¥refs[¥parentId]))
{
¥tree[] =& ¥arr[¥offset];
continue;
}
¥parent =& ¥refs[¥parentId];
¥parent[¥keyChildrens][] =& ¥arr[¥offset];
}
else
{
¥tree[] =& ¥arr[¥offset];
}
}
return ¥tree;
}
/
将树形数组展开为平面的数组
这个办法是 tree() 办法的逆向操纵。
@param array ¥tree 树形数组
@param string ¥keyChildrens 包含子节点的键名
@return array 展开后的数组
/
static function treeToArray(¥tree, ¥keyChildrens = childrens)
{
¥ret = array();
if (isset(¥tree[¥keyChildrens]) && is_array(¥tree[¥keyChildrens]))
{
foreach (¥tree[¥keyChildrens] as ¥child)
{
¥ret = array_merge(¥ret, self::treeToArray(¥child, ¥keyChildrens));
}
unset(¥node[¥keyChildrens]);
¥ret[] = ¥tree;
}
else
{
¥ret[] = ¥tree;
}
return ¥ret;
}
/
按照指定的键对数组排序
用法:
@code php
¥rows = array(
array(id => 1, value => 1-1, parent => 1),
array(id => 2, value => 2-1, parent => 1),
array(id => 3, value => 3-1, parent => 1),
array(id => 4, value => 4-1, parent => 2),
array(id => 5, value => 5-1, parent => 2),
array(id => 6, value => 6-1, parent => 3),
);
¥rows = ArrayHelper::sortByCol(¥rows, id, SORT_DESC);
dump(¥rows);
// 输出成果为:
// array(
// array(id => 6, value => 6-1, parent => 3),
// array(id => 5, value => 5-1, parent => 2),
// array(id => 4, value => 4-1, parent => 2),
// array(id => 3, value => 3-1, parent => 1),
// array(id => 2, value => 2-1, parent => 1),
// array(id => 1, value => 1-1, parent => 1),
// )
@endcode
@param array ¥array 要排序的数组
@param string ¥keyname 排序的键
@param int ¥dir 排序标的目标
@return array 排序后的数组
/
static function sortByCol(¥array, ¥keyname, ¥dir = SORT_ASC)
{
return self::sortByMultiCols(¥array, array(¥keyname => ¥dir));
}
/
将一个二维数组遵守多个列进行排序,类似 SQL 语句中的 ORDER BY
用法:
@code php
¥rows = ArrayHelper::sortByMultiCols(¥rows, array(
parent => SORT_ASC,
name => SORT_DESC,
));
@endcode
@param array ¥rowset 要排序的数组
@param array ¥args 排序的键
@return array 排序后的数组
/
static function sortByMultiCols(¥rowset, ¥args)
{
¥sortArray = array();
¥sortRule = ;
foreach (¥args as ¥sortField => ¥sortDir)
{
foreach (¥rowset as ¥offset => ¥row)
{
¥sortArray[¥sortField][¥offset] = ¥row[¥sortField];
}
¥sortRule .= ¥sortArray[\ . ¥sortField . \], . ¥sortDir . , ;
}
if (empty(¥sortArray) || empty(¥sortRule)) {
return ¥rowset;
}
eval(array_multisort( . ¥sortRule . ¥rowset););
return ¥rowset;
}
}
无论对感情还是对生活,“只要甜不要苦”都是任性而孩子气的,因为我们也不完美,我们也会伤害人。正因为我们都不完美,也因为生活从不是事事如意,所以对这些“瑕疵”的收纳才让我们对生活、对他人的爱变得日益真实而具体。—— 汪冰《世界再亏欠你,也要敢于拥抱幸福》




