aboutsummaryrefslogtreecommitdiff
path: root/files/pl/web/javascript/referencje/obiekty/array/reduceright/index.html
blob: fcb2b0e694f6ca3dab05e4e08c93c57b2d8fe4ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
---
title: Array.prototype.reduceRight()
slug: Web/JavaScript/Referencje/Obiekty/Array/ReduceRight
translation_of: Web/JavaScript/Reference/Global_Objects/Array/ReduceRight
---
<div>{{JSRef}}</div>

<p>Metoda <code><strong>reduceRight()</strong></code> przekazuje do funkcji wartość przyrostową dla każdego elementu w tablicy zaczynając od prawej do lewej (od najwyższego indexu do najniższego) w celu sprowadzenia tablicy do pojedynczej wartości.</p>

<div>{{EmbedInteractiveExample("pages/js/array-reduce-right.html","shorter")}}</div>



<p>Sprawdź również {{jsxref("Array.prototype.reduce()")}} dla redukowania tablicy od lewej do prawej (od najniższego indexu do najwyższego).</p>

<h2 id="Składnia">Składnia</h2>

<pre class="syntaxbox"><var>arr.reduceRight(callback(akumulator, obecnaWartość[, index[, tablica]])[, wartośćPoczątkowa])</var></pre>

<h3 id="Parametry">Parametry</h3>

<dl>
 <dt><code>callback</code></dt>
 <dd>Funkcja która będzie wołana dla każdego elementu w tablicy, przyjmuje 4 argumenty:
 <dl>
  <dt><code>akumulator</code></dt>
  <dd>Wartość zwrócona z poprzedniego wywołania funkcji <code>callback</code> lub <code>wartośćPoczątkowa</code>, jeśli została zdefiniowana. (Sprawdź poniżej.)</dd>
  <dt><code>obecnaWartość</code></dt>
  <dd>Element z tablicy, który aktualnie jest przetwarzany</dd>
  <dt><code>index</code>{{optional_inline}}</dt>
  <dd>Index aktualnie przetwarzanego elementu z tablicy.</dd>
  <dt><code>tablica</code>{{optional_inline}}</dt>
  <dd>Tablica, na której <code>reduceRight()</code> zostało zawołane.</dd>
 </dl>
 </dd>
 <dt><code>wartośćPoczątkowa</code>{{optional_inline}}</dt>
 <dd>Wartość, która zostanie użyta do pierwszego wykonania funkcji <code>callback</code>. Jeśli wartość ta nie zostanie zdefiniowana, ostatni element tablicy zostanie użyty i pominięty. Wołanie reduce lub reduceRight na pustej tablicy bez zdefiniowanej wartości początkowej spowoduje błąd <code>TypeError</code>.</dd>
</dl>

<h3 id="Wartość_zwracana">Wartość zwracana</h3>

<p>Wartość wynikowa redukcji.</p>

<h2 id="Opis">Opis</h2>

<p><code>reduceRight</code> wykonuje funkcję <code>callback</code> dla każdego elementu z tablicy, z wyłączeniem miejsc niezdefiniowanych w tablicy, przekazując cztery argumenty: wartość początkową (lub wartość z poprzedniego wywołania funkcji <code>callback</code>), wartość obecnie przetwarzanego elementu, obecny index oraz tablicę na której wykonywane są iteracje.</p>

<p>Użycie funkcji <code>callback</code> w metodzie reduceRight może wyglądac następująco:</p>

<pre class="brush: js">array.reduceRight(function(akumulator, obecnaWartość, index, tablica) {
  // ...
});
</pre>

<p>Przy pierwszym wywołaniu funkcji, <code>akumulator</code> i <code>obecnaWartość</code> mogą mieć jedną z 2 wartości. Jeśli <code>wartośćPoczątkowa</code> została przekazana do <code>reduceRight</code>, to <code>akumulator</code> będzie równy <code>wartośćPoczątkowa</code><code>obecnaWartość</code> będzie równa ostatniej wartości z tablicy. Jeśli <code>wartośćPoczątkowa</code> nie została zdefiniowana, wtedy <code>akumulator</code> będzie równy ostatniej wartości z tablicy a <code>obecnaWartość</code> będzie równa przedostatniej wartości z tablicy.</p>

<p>Jeśli tablica jest pusta i <code>wartośćPoczątkowa</code> nie została zdefiniowana, spowoduje to błąd: {{jsxref("TypeError")}}. Jeśli tablica ma tylko jeden element (niezależnie od jego pozycji) i <code>wartośćPoczątkowa</code> nie została zdefiniowana lub <code>wartośćPoczątkowa</code> została zdefiniowana ale tablica jest pusta, to ta pojedyncza wartość zostanie zwrócona bez wołania funkcji <code>callback</code>.</p>

<p>Przykład pokazujący, jak przepływają dane do funkcji <code>callback</code>:</p>

<pre class="brush: js">[0, 1, 2, 3, 4].reduceRight(function(akumulator, obecnaWartość, index, tablica) {
  return akumulator + obecnaWartość;
});
</pre>

<p>Funkcja <code>callback</code> wykona się 4 razy a argumenty wywołań oraz wartości zwracane będą zgodne z poniższą tabelą:</p>

<table>
 <thead>
  <tr>
   <th scope="col"><code>callback</code></th>
   <th scope="col"><code>akumulator</code></th>
   <th scope="col"><code>obecnaWartość</code></th>
   <th scope="col"><code>index</code></th>
   <th scope="col"><code>tablica</code></th>
   <th scope="col">zwrócona wartość</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <th scope="row">first call</th>
   <td><code>4</code></td>
   <td><code>3</code></td>
   <td><code>3</code></td>
   <td><code>[0, 1, 2, 3, 4]</code></td>
   <td><code>7</code></td>
  </tr>
  <tr>
   <th scope="row">second call</th>
   <td><code>7</code></td>
   <td><code>2</code></td>
   <td><code>2</code></td>
   <td><code>[0, 1, 2, 3, 4]</code></td>
   <td><code>9</code></td>
  </tr>
  <tr>
   <th scope="row">third call</th>
   <td><code>9</code></td>
   <td><code>1</code></td>
   <td><code>1</code></td>
   <td><code>[0, 1, 2, 3, 4]</code></td>
   <td><code>10</code></td>
  </tr>
  <tr>
   <th scope="row">fourth call</th>
   <td><code>10</code></td>
   <td><code>0</code></td>
   <td><code>0</code></td>
   <td><code>[0, 1, 2, 3, 4]</code></td>
   <td><code>10</code></td>
  </tr>
 </tbody>
</table>

<p>Wartość zwrócona przez <code>reduceRight</code> będzie tym, co zostało zwrócone przez ostatnie wywołanie funkcji <code>callback</code> (<code>10</code>).</p>

<p>Jeśli <code>wartośćPoczątkowa</code> zostałaby zdefiniowana wyniki wyglądałyby następująco:</p>

<pre class="brush: js">[0, 1, 2, 3, 4].reduceRight(function(akumulator, obecnaWartość, index, tablica) {
  return akumulator + obecnaWartość;
}, 10);
</pre>

<table>
 <thead>
  <tr>
   <th scope="col"><code>callback</code></th>
   <th scope="col"><code>akumulator</code></th>
   <th scope="col"><code>obecnaWartość</code></th>
   <th scope="col"><code>index</code></th>
   <th scope="col"><code>tablica</code></th>
   <th scope="col">zwrócona wartość</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <th scope="row">first call</th>
   <td><code>10</code></td>
   <td><code>4</code></td>
   <td><code>4</code></td>
   <td><code>[0, 1, 2, 3, 4]</code></td>
   <td><code>14</code></td>
  </tr>
  <tr>
   <th scope="row">second call</th>
   <td><code>14</code></td>
   <td><code>3</code></td>
   <td><code>3</code></td>
   <td><code>[0, 1, 2, 3, 4]</code></td>
   <td><code>17</code></td>
  </tr>
  <tr>
   <th scope="row">third call</th>
   <td><code>17</code></td>
   <td><code>2</code></td>
   <td><code>2</code></td>
   <td><code>[0, 1, 2, 3, 4]</code></td>
   <td><code>19</code></td>
  </tr>
  <tr>
   <th scope="row">fourth call</th>
   <td><code>19</code></td>
   <td><code>1</code></td>
   <td><code>1</code></td>
   <td><code>[0, 1, 2, 3, 4]</code></td>
   <td><code>20</code></td>
  </tr>
  <tr>
   <th scope="row">fifth call</th>
   <td><code>20</code></td>
   <td><code>0</code></td>
   <td><code>0</code></td>
   <td><code>[0, 1, 2, 3, 4]</code></td>
   <td><code>20</code></td>
  </tr>
 </tbody>
</table>

<p>Wartość zwrócona przez <code>reduceRight</code> w tym przypadku, będzie, oczywiście, <code>20</code>.</p>

<h2 id="Przykłady">Przykłady</h2>

<h3 id="Zsumuj_wszystkie_wartości_z_tablicy">Zsumuj wszystkie wartości z tablicy</h3>

<pre class="brush: js">var sum = [0, 1, 2, 3].reduceRight(function(a, b) {
  return a + b;
});
// sum is 6
</pre>

<h3 id="Spłaszcz_tablicę_tablic">Spłaszcz tablicę tablic</h3>

<pre class="brush: js">var flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
    return a.concat(b);
}, []);
// flattened is [4, 5, 2, 3, 0, 1]

</pre>

<h3 id="Uruchom_asynchroniczne_funkcje_z_callbackami_z_listy_w_taki_sposób_aby_każda_przekazywała_wynik_wykonania_do_następnej">Uruchom asynchroniczne funkcje z callbackami z listy w taki sposób aby każda przekazywała wynik wykonania do następnej</h3>

<pre class="brush: js">const waterfall = (...functions) =&gt; (callback, ...args) =&gt;
  functions.reduceRight(
    (composition, fn) =&gt; (...results) =&gt; fn(composition, ...results),
    callback
  )(...args);

const randInt = max =&gt; Math.floor(Math.random() * max)

const add5 = (callback, x) =&gt; {
  setTimeout(callback, randInt(1000), x + 5);
};
const mult3 = (callback, x) =&gt; {
  setTimeout(callback, randInt(1000), x * 3);
};
const sub2 = (callback, x) =&gt; {
  setTimeout(callback, randInt(1000), x - 2);
};
const split = (callback, x) =&gt; {
  setTimeout(callback, randInt(1000), x, x);
};
const add = (callback, x, y) =&gt; {
  setTimeout(callback, randInt(1000), x + y);
};
const div4 = (callback, x) =&gt; {
  setTimeout(callback, randInt(1000), x / 4);
};

const computation = waterfall(add5, mult3, sub2, split, add, div4);
computation(console.log, 5) // -&gt; 14

// same as:

const computation2 = (input, callback) =&gt; {
  const f6 = x=&gt; div4(callback, x);
  const f5 = (x, y) =&gt; add(f6, x, y);
  const f4 = x =&gt; split(f5, x);
  const f3 = x =&gt; sub2(f4, x);
  const f2 = x =&gt; mult3(f3, x);
  add5(f2, input);
}</pre>

<h3 id="​​​​​​Różnica_pomiędzy_reduce_i_reduceRight">​​​​​​Różnica pomiędzy <code>reduce</code> i <code>reduceRight</code></h3>

<pre class="brush: js">var a = ['1', '2', '3', '4', '5'];
var left  = a.reduce(function(prev, cur)      { return prev + cur; });
var right = a.reduceRight(function(prev, cur) { return prev + cur; });

console.log(left);  // "12345"
console.log(right); // "54321"</pre>

<h3 id="Przykład_na_rozwijanie_funkcji">Przykład na rozwijanie funkcji</h3>

<p>W rozwijaniu funkcji chodzi o to, że w wywołaniu jednej funkcji możemy użyć wielu funkcji. Odbywa się to od prawej do lewej, wołając każdą funkcję z wynikiem zwróconym przez poprzednią.</p>

<pre class="brush: js">/**
 * Function Composition is way in which result of one function can
 * be passed to another and so on.
 *
 * h(x) = f(g(x))
 *
 * Function execution happens right to left
 *
 * https://en.wikipedia.org/wiki/Function_composition
 */

const compose = (...args) =&gt; (value) =&gt; args.reduceRight((acc, fn) =&gt; fn(acc), value)

// Increment passed number
const inc = (n) =&gt; n + 1

// Doubles the passed value
const double = (n) =&gt; n * 2

// using composition function
console.log(compose(double, inc)(2)); // 6

// using composition function
console.log(compose(inc, double)(2)); // 5
</pre>

<h2 id="Polyfill">Polyfill</h2>

<p><code>reduceRight</code> zostało dodane dostandardu ECMA-262 w piątej edycji, w związku z czym może jeszcze nie być dodane do wszystkich implementacji standardu. Można to rozwiązać poprzez użycie poniższego kodu na początku aplikacji, pozwoli to na używanie <code>reduceRight</code> w środowiskach, które tego nie implementują.</p>

<pre class="brush: js">// Production steps of ECMA-262, Edition 5, 15.4.4.22
// Reference: http://es5.github.io/#x15.4.4.22
if ('function' !== typeof Array.prototype.reduceRight) {
  Array.prototype.reduceRight = function(callback /*, initialValue*/) {
    'use strict';
    if (null === this || 'undefined' === typeof this) {
      throw new TypeError('Array.prototype.reduce called on null or undefined');
    }
    if ('function' !== typeof callback) {
      throw new TypeError(callback + ' is not a function');
    }
    var t = Object(this), len = t.length &gt;&gt;&gt; 0, k = len - 1, value;
    if (arguments.length &gt;= 2) {
      value = arguments[1];
    } else {
      while (k &gt;= 0 &amp;&amp; !(k in t)) {
        k--;
      }
      if (k &lt; 0) {
        throw new TypeError('Reduce of empty array with no initial value');
      }
      value = t[k--];
    }
    for (; k &gt;= 0; k--) {
      if (k in t) {
        value = callback(value, t[k], k, t);
      }
    }
    return value;
  };
}
</pre>

<h2 id="Specyfikacje">Specyfikacje</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specyfikacja</th>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-array.prototype.reduceright', 'Array.prototype.reduceRight')}}</td>
  </tr>
 </tbody>
</table>

<h2 id="Zgodność_w_przeglądarkach">Zgodność w przeglądarkach</h2>

<div>


<p>{{Compat("javascript.builtins.Array.reduceRight")}}</p>
</div>

<h2 id="Sprawdź_również">Sprawdź również</h2>

<ul>
 <li>{{jsxref("Array.prototype.reduce()")}}</li>
</ul>