Muszę podzielić tablicę JavaScript na n
mniejsze części.
Np .: Biorąc pod uwagę tę tablicę
["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"]
a n
równa się 4, wynik powinien wyglądać następująco:
[ ["a1", "a2", "a3", "a4"],
["a5", "a6", "a7", "a8"],
["a9", "a10", "a11", "a12"],
["a13"]
]
Zdaję sobie sprawę z czystych rozwiązań JavaScript dla tego problemu, ale ponieważ korzystam już z Lodash , zastanawiam się, czy Lodash zapewnia lepsze rozwiązanie tego problemu.
Edytować:
Stworzyłem test jsPerf, aby sprawdzić, o ile wolniejsze jest rozwiązanie podkreślające.
javascript
split
functional-programming
underscore.js
lodash
Cesar Canassa
źródło
źródło
W przypadku rozwiązania opartego na podkreśleniu spróbuj tego:
var data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"]; var n = 3; var lists = _.groupBy(data, function(element, index){ return Math.floor(index/n); }); lists = _.toArray(lists); //Added this to convert the returned object to an array. console.log(lists);
Używając metody chain wrapper, możesz połączyć te dwie instrukcje jak poniżej:
var data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"]; var n = 3; var lists = _.chain(data).groupBy(function(element, index){ return Math.floor(index/n); }).toArray() .value();
źródło
groupBy
funkcja Underscore zwraca obiekt , a nie tablicę. Nie jest to przełom - otrzymujesz zasadniczo tę samą funkcjonalność - ale dziwną semantykę. Edycja: Och, robi to, aby zachować łańcuchowość. Wciąż interesujące.splice
w pętli jest nadal trójliniowy i, jak sądzę, o wiele bardziej wydajny. Jeśli twoje tablice są krótkie, prawdopodobnie nie ma to znaczenia, ale jeśli masz do czynienia z setkami lub tysiącami elementów, miej oko na ich wydajność.Prawdopodobnie prostsze wyrażenie:
const coll = [ "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9" ]; const n = 2; const chunks = _.range(coll.length / n).map(i => coll.slice(i * n, (i + 1) * n)); console.log(chunks);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
źródło
Podkreślenie obsługuje natywnie _.chunk () od wersji 1.9.0.
const data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"]; const chunks = _.chunk(data, 4); console.log(chunks);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore.js"></script>
źródło
spróbuj tego, jest o wiele bardziej praktyczny (na przykład, jeśli chcesz podzielić tablicę na podstawie ilości elementów, które mają być kontenerami w każdej pod macierzy):
function chunk(arr, start, amount){ var result = [], i, start = start || 0, amount = amount || 500, len = arr.length; do { //console.log('appending ', start, '-', start + amount, 'of ', len, '.'); result.push(arr.slice(start, start+amount)); start += amount; } while (start< len); return result; };
i zastosowanie w twoim przypadku:
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17], chunked = chunk(arr, 0, Math.floor(arr.length/3)); //to get 4 nested arrays console.log(chunked);
i inny przypadek:
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17], chunked = chunk(arr, 0, 3); // to get 6 nested arrays each containing maximum of 3 items console.log(chunked);
źródło
start
parametr nie jest naprawdę praktyczny, imho. Zwykle nie chciałbyś tego zdać; ale zawsze musisz określić rozmiar porcji. Lepiej zamień te dwa parametry.do while
pętla? Nikt nie chce dostawać pustych kawałków.