2014-01-24 3 views
1

Пусть это мой вклад: "0.1412898495873448 -0.03307049805768848 -0.0002348551519150674 0.0007142371877833145 -0.01250041632738383 0.4052674201000387 -0.02541421100956797 -0.02842612870208528 1803.701163338969 1796.443677744862 1986.31441429052 1442.354524622483"Что такое элегантный способ определения функции «группировки» массива?

Сильвестра имеет this конструктор. Для этого требуется вложенный массив.

Достаточно просто сделать строку в массив чисел, используя String.split() и map и друзей.

Что-то не в отличие от этого:

var nums = line.split(/ |\n/); 
nums.map(function(num) {return parseFloat(num);}); 

Но я думаю, что Javascript отсутствует функция функционального стиля, который может «группа» моя 16-массив в 4 ряда по 4 цифр.

Я подумал, может быть, полезная библиотека JS, такая как underscore, могла бы меня охватить.

Не похоже.

Какой самый элегантный и/или эффективный способ сделать это? У меня есть, чтобы использовать цикл for?

function nest(array, range) { 
    var l = array.length; 
    var ret = []; 
    var cur = null; 
    for (var i=0; i<l; ++i) { 
     if (!(i%range)) { 
      cur = []; 
      ret.push(cur); 
     } 
     cur.push(array[i]); 
    } 
    return ret; 
} 

Node говорит мне, что это работает:

> function nest(array, range) { 
...  var l = array.length; 
...  var ret = []; 
...  var cur = null; 
...  for (var i=0; i<l; ++i) { 
.....   if (!(i%range)) { 
.......    cur = []; 
.......    ret.push(cur); 
.......   } 
.....   cur.push(array[i]); 
.....  } 
...  return ret; 
... } 
undefined 
> nest([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],4) 
[ [ 0, 1, 2, 3 ], 
    [ 4, 5, 6, 7 ], 
    [ 8, 9, 10, 11 ], 
    [ 12, 13, 14, 15 ] ] 
> 

Можно ли придумать лучший способ сделать это?

+0

То, что вы делаете, кажется прекрасным. Вероятно, есть много способов сделать это, вот один из них -> http://jsfiddle.net/C6L6g/, но я действительно думаю, что вы делаете это лучше. – adeneo

+0

Вы можете упростить 'nums.map (parseFloat)' – elclanrs

+2

Возможный дубликат: http://stackoverflow.com/questions/8495687/split-array-into-chunks – basilikum

ответ

2

Есть несколько способов разбиения массива в подмассивы

var line = "0.1412898495873448 -0.03307049805768848 -0.0002348551519150674 0.0007142371877833145 -0.01250041632738383 0.4052674201000387 -0.02541421100956797 -0.02842612870208528 1803.701163338969 1796.443677744862 1986.31441429052 1442.354524622483"; 

var nums = line.split(/ |\n/).map(parseFloat); 
var columns = 4; 
var nested = []; 
for (var i=0; i < nums.length; i+=columns) { 
    nested.push(nums.slice(i, i+columns)); 
} 

console.log(nested); 

Или функционально:

var nested = Array.apply(null, new Array((nums.length/columns)|0)) 
       .map(function(item, index) { 
        return nums.slice(index*columns, (index+1) * columns); 
       }); 

Использование сращивания вместо среза, кажется, гораздо лучше, хотя это может быть связанно в плохо написана tests

var columns = 4; 
var nested = []; 
for (var i=nums.length/columns; i--;) { // gives expected result if columns===0 
    nested.push(nums.splice(0,columns)); 
} 

в качестве альтернативы:

var columns = 4; 
var nested = []; 
while(nums.length) nested.push(nums.splice(0,columns)); 
+0

Slice, вероятно, билет. Лучше, чем называть толчок снова и снова. –

+0

Посмотрите на тест производительности в своем ответе, я был так заинтересован, я думаю, что мой гораздо быстрее, потому что я избегаю.map dont know –

+0

@johnSmith Я принимаю первый код, второй явно не может быть выполнен. (Ваш список кодов более или менее тот, который я изначально придумал) –

0

Вот мой подход,

var nums = line.split(/ |\n/); 
var temp=[],output=[],i=0; 
while(i<nums.length){ 
    temp.push(i); 
    if(i%4 == 0){ 
     output.push(temp); 
     temp=[]; 
    } 
    i++ 
} 
console.dir(output); 

Для моих чувств это prettty быстро! проверить этот тест производительности на принятый ответ http://jsperf.com/comparing-use-of-modulo-vs-slice-in-a-special-case

+0

Ваш jsPerf довольно предвзятый, не говоря уже о неправильном. Некоторые очевидные проблемы заключаются в том, что вы добавили parseFloat к моему решению, которое отсутствует у вас. Это не имеет большого значения, потому что вы фактически не просматриваете номера/строки в своем решении, вы просто добавляете индекс в выходные массивы. Я исправил его здесь, и решение среза будет как можно быстрее как в этом конкретном случае, так и в больших массивах, где производительность действительно имеет значение: http://jsperf.com/comparing-use-of-modulo-vs-slice-in-a- специальный корпус/2 – Tibos

+0

Кроме того, я добавил случай сращивания, который по какой-то причине намного быстрее, чем версия среза. Я предполагаю, что есть какая-то сумасшедшая оптимизация V8, но все же, если вы хотите пойти на производительность, это, вероятно, решение для использования. – Tibos

+0

да, это было похоже на то, что я хотел прокомментировать «им слишком ленив, чтобы проверить, если это быстро», поэтому я закончил свой первый тестовый лист js performance: D, но в вашем новом тестовом листе вы включили функцию карты в процессе подготовки код, который не включен в мою попытку и не нужен, так что причина в том, что если я удалю его, я снова быстрее;) –

Смежные вопросы