объеденить строчки json

377
14 октября 2017, 20:48

Имеется такой json:

{art: "1", quan: "1", sum: "1"}
{art: "2", quan: "1", sum: "1"}
{art: "1", quan: "1", sum: "1"}
{art: "12", quan: "1", sum: "1"}
{art: "1", quan: "1", sum: "1"}
{art: "12", quan: "1", sum: "1"}
{art: "1", quan: "1", sum: "1"}
{art: "11", quan: "1", sum: "1"}
{art: "1", quan: "1", sum: "1"}

Подскажите, как мне найти повторы по полю 'art', удалить повторы и сложить поля quan и sum.

То есть в итоге должно получиться :

{art: "1", quan: "4", sum: "4"}
{art: "2", quan: "1", sum: "1"}
{art: "12", quan: "2", sum: "2"}
{art: "11", quan: "1", sum: "1"}

Код:

function filterArt(arr) {
    for (var i = 0; i < arr.length; i++) {
        for (var j = i + 1; j < arr.length - i; j++) {
            if (arr[i].art == arr[j].art){
                arr[i].quan = +arr[i].quan + (+arr[j].quan);
                arr[i].sum = +arr[i].sum + (+arr[j].sum);
                arr.splice(j,1);
            }
        }
    }
}

Код не совершенен. Подскажите, пожалуйста, в какую сторону копать.

Answer 1

Вы ошиблись когда сделали во втором цикле j < arr.length - i: Тогда в определенных случаях, ваш i элемент не сравнится с последними элементами массива.

var arr = [ 
    {art: "1", quan: "1", sum: "1"}, 
    {art: "2", quan: "1", sum: "1"}, 
    {art: "1", quan: "1", sum: "1"}, 
    {art: "12", quan: "1", sum: "1"}, 
    {art: "1", quan: "1", sum: "1"}, 
    {art: "12", quan: "1", sum: "1"}, 
    {art: "1", quan: "1", sum: "1"}, 
    {art: "11", quan: "1", sum: "1"}, 
    {art: "1", quan: "1", sum: "1"} 
]; 
 
function filterArt(arr) { 
    for (var i = 0; i < arr.length; i++) { 
        for (var j = i + 1; j < arr.length; j++) { 
            if (arr[i].art == arr[j].art) { 
                arr[i].quan = +arr[i].quan + (+arr[j].quan); 
                arr[i].sum = +arr[i].sum + (+arr[j].sum); 
                arr.splice(j, 1); 
            } 
        } 
    } 
    return arr; 
} 
console.log(filterArt(arr));

Answer 2

Вы в вашем алгоритме для каждого элемента массива пробегаетесь по всем другим элементам, в итоге сложность получается O(n^2). Проще Завести один объект и пробегаться по всем существующим и уже дальше смотреть - если есть элемент с таким arr (сделать его индексом), то приплюсовывать значения. Если же такого нет - то создавать, с теми значениями что у текущего объекта.

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

var objs = {}; 
$('.json').each(function(){ 
  var obj = JSON.parse($(this).html()); 
  if (objs[obj.art]){ 
    objs[obj.art].quan += parseInt(obj.quan); 
    objs[obj.art].sum += parseInt(obj.sum); 
  } else { 
    objs[obj.art] = { 
      quan: parseInt(obj.quan), 
      sum: parseInt(obj.sum) 
    } 
  } 
}); 
 
$('.result').html(JSON.stringify(objs));
.json{ 
  display: none; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="json">{"art": "1", "quan": "1", "sum": "1"}</div> 
<div class="json">{"art": "2", "quan": "1", "sum": "1"}</div> 
<div class="json">{"art": "1", "quan": "1", "sum": "1"}</div> 
<div class="json">{"art": "12", "quan": "1", "sum": "1"}</div> 
<div class="json">{"art": "1", "quan": "1", "sum": "1"}</div> 
<div class="json">{"art": "12", "quan": "1", "sum": "1"}</div> 
<div class="json">{"art": "1", "quan": "1", "sum": "1"}</div> 
<div class="json">{"art": "11", "quan": "1", "sum": "1"}</div> 
<div class="json">{"art": "1", "quan": "1", "sum": "1"}</div> 
 
<div class="result"></div>

Answer 3

убрал второй for из примера @Razmik Galstyan

var arr = [ 
    {art: "1", quan: "1", sum: "1"}, 
    {art: "2", quan: "1", sum: "1"}, 
    {art: "1", quan: "1", sum: "1"}, 
    {art: "12", quan: "1", sum: "1"}, 
    {art: "1", quan: "1", sum: "1"}, 
    {art: "12", quan: "1", sum: "1"}, 
    {art: "1", quan: "1", sum: "1"}, 
    {art: "11", quan: "1", sum: "1"}, 
    {art: "1", quan: "1", sum: "1"} 
]; 
function filterArt(arr) { 
    var obj = {}; 
    for (var i = 0; i < arr.length;) { 
        var art = arr[i].art, 
            j = obj[art]; 
        if (j !== void 0) { 
            arr[j].quan = +arr[i].quan + +arr[j].quan; 
            arr[j].sum = +arr[i].sum + +arr[j].sum; 
            arr.splice(i, 1) 
        } else obj[art] = i++ 
    } 
    return arr 
}; 
console.log(filterArt(arr));

READ ALSO
Скомпонировать JSON сртроку

Скомпонировать JSON сртроку

Добрый день, есть JSON строка в которой много ошибок

253
Angular2 создать Dom вписать значения из массива

Angular2 создать Dom вписать значения из массива

Добрый день, с Angular работаю впервые, пока кажется очень сложным и непонятным, но работать приходится, возникла проблема, Необходимо создавать...

342
Интернет-магазин с Angular, хорошая ли идея? [требует правки]

Интернет-магазин с Angular, хорошая ли идея? [требует правки]

Если бы не было проблем с индексированием топовыми поисковиками сайтов, полностью рендерихщася на фронте (когда бэк отдает только json) - то этот...

541