2016-06-03 6 views
0

вот мой код:Рекурсия: Как я могу удалить

var asset = ['1234_12', '1234_34', '1234_33', '4321_22', '4321_90']; 

var largest = removeElements(asset); 

function removeElements(asset) { 
    var retVal = []; 
    for (i = 0; i < asset.length; i++) { 
     for (var j = 0; j < asset.length; j++) { 
      if (asset[i].split('_')[0] == asset[j].split('_')[0]) { 
       if (asset[i].split('_')[1].split('.')[0] > asset[j].split('_')[1].split('.')[0]) { 
        retVal = removeElements(asset, asset[j]); 
        for (var k = 0; k < retVal.length; k++) { 
         for (var l = 0; l < retVal.length; l++) { 
          if (retVal[k].split('_')[0] == retVal[l].split('_')[0]) { 
           removeElements(retVal); 
          } else { 
           return retVal; 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
    return retVal; 
} 

Вот структура массива:

var asset = ['1234_12', '1234_34', '1234_33', '4321_22', '4321_90']; 

То, что я хочу, чтобы получить самый большой в '1234' или '4321' серии. Например, в этом случае мне нужно захватить '1234_34' и '4321_90'.

RangeError: Maximum call stack size exceeded

Что я делаю неправильно?

+6

Действительно ли это? – jsfrocha

+0

Да. Обновлен код. –

+0

Для каждой «категории номеров» (1234) я бы использовал карту для преобразования всех элементов массива в «последний» номер, а затем отфильтровал его до самого высокого из этих чисел. Готово. – evolutionxbox

ответ

4

Вы делаете это сложнее, чем это для себя. Вы можете просто перебирать каждый элемент и хранить совпавшие значения в объекте:

var asset = ['1234_12', '1234_34', '1234_33', '4321_22', '4321_90']; 
var intermediate = {}; 
asset.forEach(function(v) { 
    var parts = v.split('_'); 
    var key = parts[0]; 
    var val = parts[1]; 
    if (!intermediate[key] || intermediate[key] < val) { 
    intermediate[key] = val; 
    } 
}); 

Это произведет объект, как:

{"1234": "34", "4321": "90"} 

который затем может быть превращен в ожидаемом массив:

var output = Object.keys(intermediate).map(function(key) { 
    return key + '_' + intermediate[key]; 
}); 
console.log(output); // ["1234_34", "4321_90"] 

Посмотрите на .forEach, .map и Object.keys

+0

Работал как шарм. Спасибо @andlrc и другим за помощь и предложения. –

+3

@SeattleAls Теперь пришло время прочитать его дважды и переписать его самостоятельно :-) – andlrc

4

Вот пример того, что будет захватывать эти значения (см jsbin):

var asset = ['1234_12', '1234_34', '1234_33', '4321_22', '4321_90']; 

var ids = _.values(_.mapValues(asset.reduce(function(agg, curr) { 
    var parts = curr.split('_'); 

    agg[parts[0]] = agg[parts[0]] || []; 

    agg[parts[0]].push(parts[1]); 

    return agg; 
}, {}), function(value, key) { 
    return [key, Math.max.apply(Math, value)].join('_'); 
})); 

console.log(ids); // => ["1234_34", "4321_90"] 

Он использует lodash для удобства, но принципы остаются теми же без него.

Сначала вы разделяете каждую строку на пару с ключом-префиксом и суффикс (так 1234_12 и 1234_34 и т. Д., Становится как { 1234: ['12', '34'] }). Затем вы просто найдете максимальное значение в этом массиве и присоедините его обратно своим ключом.

+0

Я думаю, вы можете изменить '_.values ​​(_. MapValues ​​(asset.reduce (...), ...), ...)' на что-то вроде '_ (asset) .reduce (...). mapValues ​​(...). values ​​(...). value() ' – andlrc

+0

@andlrc да, хороший вызов с цепочкой (определенно более читаемый) –

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