2015-02-10 1 views
1

У меня есть массив, например:значение массива в группы, которые находятся в том же диапазоне, кратные 10

var arr = [2,4,7,11,25,608,65,109,99,100,504,606,607]; 

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

Например, 2,4,7 находятся между 0 и 10, поэтому они должны быть вместе. 11 был бы один в своей группе, например, 25,65 и т. Д. 606,607,608 было бы вместе.

Массив выше должно стать:

[ [2,4,7],[11],[25],[65],[99],[101],[504],[100,109],[606,607,608] ]

Я думал об этом в течение нескольких часов, и я не смог придумать ничего еще. Это очень плохо, не так много стоит упомянуть, но до сих пор я играю с Math.round (http://jsfiddle.net/40napnyx/2/)

Edit: Я хотел бы добавить еще один вопрос (хотя я не буду выбирать правильный ответ на основе этого, если фактические ответы не включают решение этой новой проблемы).

Массив может содержать значения с буквами. Эти значения должны быть в одной и той же группе в алфавитном порядке (для определения ордера берется только первая буква). Эта группа должна быть последним значением в результирующем массиве.

Так, например var arr = [2, 4, 11,'a3', 25, 7, 'j', 'bzy4];

будет ли [[2,4,7],[11],[25],['a3','bzy4', 'j']]

+0

Где ваш первоначальный 'arr' массив в скрипку? что вы пытаетесь сделать с математикой? Что насчет номеров '10' и' 100'? –

+0

В скрипте цикл for выглядит так, как будто массив содержит числа от 0-21. –

+0

2,4,7 находятся между 0 (предыдущий кратный 10 из этих чисел) и 10 (их следующий кратный 10), поэтому они должны быть сгруппированы вместе. –

ответ

5

Вот общая функция:

function groupBy(ary, keyFunc) { 
 
    var r = {}; 
 
    ary.forEach(function(x) { 
 
    var y = keyFunc(x); 
 
    r[y] = (r[y] || []).concat(x); 
 
    }); 
 
    return Object.keys(r).map(function(y) { 
 
    return r[y]; 
 
    }); 
 
} 
 

 
// usage: 
 

 
var arr = [2,4,7,11,25,608,65,99,101,504,606,607]; 
 

 
g = groupBy(arr, function(x) { return Math.floor(x/10) }); 
 

 
document.write(JSON.stringify(g));

Для бонусный вопрос, просто применить groupBy дважды:

function groupBy(ary, keyFunc) { 
 
     var r = {}; 
 
     ary.forEach(function(x) { 
 
     var y = keyFunc(x); 
 
     r[y] = (r[y] || []).concat(x); 
 
     }); 
 
     return Object.keys(r).map(function(y) { 
 
     return r[y]; 
 
     }); 
 
    } 
 

 

 

 

 

 
var arr = [2, 4, 11,'a3', 25, 7, 'j', 'bzy4']; 
 
g = groupBy(arr, isNaN); 
 

 
g = [].concat(
 
    groupBy(g[0], function(x) { return Math.floor(x/10) }), 
 
    [g[1].sort()] 
 
); 
 
      
 
document.write(JSON.stringify(g));

+0

Спасибо! Работает хорошо. Я добавил редактирование на свой пост с дополнительной проблемой и хотел бы знать, как вы справитесь с этим? –

+0

@ robertparé: см. Обновление – georg

1

Это то, что я придумал:

var arr = [2,4,7,11,25,65,99,101,504,606,607,608]; 
arr.sort(function(a, b) { 
    if(a > b) return 1; 
    if(a < b) return -1; 
    else return 0; 
}); 

var grouped_array = []; 
for(var i = 0; i < arr.length; i++) { 
    var group = []; 
    var curr_group = Math.floor(arr[i]/10); 
    while(Math.floor(arr[i]/10) == curr_group) { 
     group.push(arr[i]); 
     i++; 
    } 
    grouped_array.push(group); 
} 

http://jsfiddle.net/40napnyx/3/

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