Arrays::order_multi_dimensional()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 8
nop 3
dl 0
loc 15
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Ocrend Framewok 3 package.
5
 *
6
 * (c) Ocrend Software <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ocrend\Kernel\Helpers;
13
14
/**
15
 * Helper con funciones útiles para el tratamiento de arreglos.
16
 *
17
 * @author Brayan Narváez <[email protected]>
18
 */
19
20
class Arrays extends \Twig_Extension {
21
22
  /**
23
   * Suma los contenidos del segundo arreglo en el primer arreglo, en las coincidencias de llaves.
24
   *
25
   * Si el primer arreglo está vacío, copiará todo el segundo arreglo en el primero. 
26
   *
27
   * Si el segundo arreglo está vacío, copiará todo el primer arreglo en el segundo.
28
   *
29
   * Si el arreglo $a tiene una estructura distinta a $b, la estructura de $a queda intacta y sólamente,
30
   * se hará sumas en las posiciones donde haya coincidencias de llaves.
31
   *
32
   * El valor null será tomado como cero.
33
   *
34
   * @param array $a: Primer arreglo
35
   * @param array $b: Segundo arreglo
36
   *
37
   * @throws RuntimeException si los arreglos son de distinto nivel
38
   * @throws RuntimeException si en la posición de coincidencia no se puede realizar una operación de suma
39
   *
40
   * @return array fusión de los dos arreglos, dejando intactal estructura de $a
41
   */
42
  public static function arrays_sum(array $a, array $b) : array {
43
    # Si alguno está vacío
44
    if (sizeof($a) == 0) {
45
      return $b;
46
    } else if (sizeof($b) == 0) {
47
      return $a;
48
    }
49
50
    # Recorrer el segundo arreglo
51
    foreach ($b as $llave => $contenido) {
52
      # Verificar que no hay desnivel
53
      if (!is_array($a[$llave]) && !is_array($b[$llave])) {
54
        $a[$llave] += $b[$llave];
55
      } else {
56
        throw new \RuntimeException('Existe un problema para operar en la llave ' . $llave . '.');
57
        break;
58
      }
59
    }
60
61
    return $a;
62
  }
63
64
  /**
65
   * Dado un índice asociativo y un arreglo, devuelve el índice numérico correspondiente al asociativo
66
   *
67
   * @param string $index: Índice asociativo del arreglo
68
   * @param array $a: Arreglo a evaluar
69
   *
70
   * @return int el índice correspondiente, -1 si no existe el indice
71
   */
72
  public static function get_key_by_index(string $index, array $a) : int {
73
    $i = 0;
74
    foreach ($a as $key => $val) {
75
      if ($key == $index) {
76
        return (int) $i;
77
      }
78
      $i++;
79
    }
80
    return -1;
81
  }
82
83
  /**
84
   * Elimina todos los elementos repetidos de un array
85
   * (string) '1' se considera igual a (int) 1
86
   *
87
   * @param array $a: Arreglo a evaluar
88
   *
89
   * @return array devuelve un arreglo sin elementos repetidos
90
   * http://stackoverflow.com/questions/8321620/array-unique-vs-array-flip
91
   */
92
  public static function unique_array(array $a) : array {
93
    return array_keys(array_flip($a));
94
  }
95
96
  /**
97
    * Evalúa si un arreglo es de tipo asociativo o no
98
    *
99
    * @param array $a: Arreglo a evaluar
100
    *
101
    * @return bool false si no lo es, true si lo es
102
  */
103
  public static function is_assoc(array $a) : bool {
104
    if (sizeof($a) == 0) {
105
      return false;
106
    }
107
108
    return (bool) (array_keys($a) !== range(0, count($a) - 1));
109
  }
110
111
  /**
112
    * Evalúa si un arreglo es secuencial (de índices numéricos)
113
    *
114
    * @param array $a: Arreglo a evaluar
115
    *
116
    * @return bool false si no lo es, true si lo es
117
  */
118
  public static function is_numeric_array(array $a) : bool {
119
    return !self::is_assoc($a);
120
  }
121
122
  /**
123
    * Obtiene de forma random un elemento de un arreglo
124
    *
125
    * @param array $a: Arreglo a evaluar
126
    *
127
    * @return mixed elemento random dentro del arreglo
128
  */
129
  public static function array_random_element(array $a) {
130
    return $a[array_rand($a)];
131
  }
132
133
  /**
134
    * Ordena una matriz de mayor a menor, o menor a mayor por el valor de un campo específico
135
    *
136
    * @param array $toOrderArray : Arreglo a evaluar
137
    * @param string $field: Campo por el que se va a ordenar
138
    * @param bool $inverse: Por defecto falso, cambia el orden
139
    *
140
    * @return mixed elemento random dentro del arreglo
141
  */
142
  public static function order_multi_dimensional(array $toOrderArray, string $field, bool $inverse = false) : array {
143
    $position = array();
144
    $newRow = array();
145
    foreach ($toOrderArray as $key => $row) {
146
      $position[$key]  = $row[$field];
147
      $newRow[$key] = $row;
148
    }
149
    $inverse ? arsort($position) : asort($position);
150
    $returnArray = array();
151
152
    foreach ($position as $key => $pos) {     
153
      $returnArray[] = $newRow[$key];
154
    }
155
156
    return $returnArray;
157
  }
158
159
  /**
160
   * Se obtiene de Twig_Extension y sirve para que cada función esté disponible como etiqueta en twig
161
   *
162
   * @return array con todas las funciones con sus respectivos nombres de acceso en plantillas twig
163
   */
164
  public function getFunctions() : array {
165
    return array(
166
      new \Twig_Function('get_key_by_index', array($this, 'get_key_by_index')),
167
      new \Twig_Function('unique_array', array($this, 'unique_array')),
168
      new \Twig_Function('is_assoc', array($this, 'is_assoc')),
169
      new \Twig_Function('is_numeric_array', array($this, 'is_numeric_array')),
170
      new \Twig_Function('array_random_element', array($this, 'array_random_element')),
171
      new \Twig_Function('arrays_sum', array($this, 'arrays_sum'))
172
    );
173
  }
174
175
  /**
176
   * Identificador único para la extensión de twig
177
   *
178
   * @return string con el nombre de la extensión
179
   */
180
  public function getName() : string {
181
    return 'ocrend_framework_helper_arrays';
182
  }
183
184
}