Вывод функции заменяет первые две строки моей основной строки JSON - PullRequest
0 голосов
/ 12 октября 2018

У меня есть запрос JSON, и я использую console.log для его представления:

var json_data = {"headers":["Month","Value","Number"],"rows":[["2018-10-01 00:00:00.0","one",209],["2018-09-01 00:00:00.0","one",274],["2018-09-01 00:00:00.0","five",183],["2018-10-01 00:00:00.0","five",164],["2018-09-01 00:00:00.0","four",214],["2018-10-01 00:00:00.0","four",192],["2018-09-01 00:00:00.0","three",128],["2018-10-01 00:00:00.0","three",125],["2018-09-01 00:00:00.0","two",199],["2018-10-01 00:00:00.0","two",169],["2018-09-01 00:00:00.0","seven",10541],["2018-10-01 00:00:00.0","seven",6139],["2018-10-01 00:00:00.0","six",169],["2018-09-01 00:00:00.0","six",233]]};

document.getElementById("original").innerHTML = json_data.rows;
 
<div style="background:yellow; "id="original"></div>
<div style="background:red;" id="output"></div>

А для значения «один» у меня есть два числа ( 209 и 274 ).

Затем я использую функцию для группировки, которая работает нормально (вывод).Моя проблема в том, что когда я использую console.log для начального запроса json_data, первые две строки отличаются.Кажется, моя функция заменила первые две строки на строки вывода (красного цвета).Функция приведена здесь:

    function initialGroupBy(rows) {
  const 
    rowMap = new Map(),
    result = [],
    dataTemp = [];

  // Iterate over the rows.
  rows.forEach(row => {

    const
      // Create a key, it is the first elements joined together.
      key = row.slice(0,1).join();

    // Check if the Map has the generated key...
    if (rowMap.has(key)) {
      // The map has the key, we need to add up the values
      const
        // Get the value for the current key.
        storedRow = rowMap.get(key);
        // Add the value of the current row to the row in the map.
        storedRow[2] += row[2];

    } else {
      // The key doens't exist yet, add the row to the map.
      rowMap.set(key, row);
    }

  });

  // Iterate over all the entries in the map and push each value with the
  // summed up value into the array.
  rowMap.forEach(value => {
    result.push(value);
  });


    for (i = 0; i < result.length; i++) 
    {
    var object2 = {"date": result[i][0].slice(0,7), "num": result[i][2]};
    dataTemp.push(object2);      
    }

    return dataTemp;

}

Полный фрагмент можно найти здесь (Сравните первые две строки желтого поля из двух фрагментов):

var json_data = {"headers":["Month","Value","Number"],"rows":[["2018-10-01 00:00:00.0","one",209],["2018-09-01 00:00:00.0","one",274],["2018-09-01 00:00:00.0","five",183],["2018-10-01 00:00:00.0","five",164],["2018-09-01 00:00:00.0","four",214],["2018-10-01 00:00:00.0","four",192],["2018-09-01 00:00:00.0","three",128],["2018-10-01 00:00:00.0","three",125],["2018-09-01 00:00:00.0","two",199],["2018-10-01 00:00:00.0","two",169],["2018-09-01 00:00:00.0","seven",10541],["2018-10-01 00:00:00.0","seven",6139],["2018-10-01 00:00:00.0","six",169],["2018-09-01 00:00:00.0","six",233]]};

function initialGroupBy(rows) {
  const 
    rowMap = new Map(),
    result = [],
    dataTemp = [];
    
  // Iterate over the rows.
  rows.forEach(row => {
  
    const
      // Create a key, it is the first elements joined together.
      key = row.slice(0,1).join();
      
    // Check if the Map has the generated key...
    if (rowMap.has(key)) {
      // The map has the key, we need to add up the values
      const
        // Get the value for the current key.
        storedRow = rowMap.get(key);
        // Add the value of the current row to the row in the map.
        storedRow[2] += row[2];
        
    } else {
      // The key doens't exist yet, add the row to the map.
      rowMap.set(key, row);
    }

  });
  
  // Iterate over all the entries in the map and push each value with the
  // summed up value into the array.
  rowMap.forEach(value => {
    result.push(value);
  });
    

	for (i = 0; i < result.length; i++) 
	{
    var object2 = {"date": result[i][0].slice(0,7), "num": result[i][2]};
    dataTemp.push(object2);      
	}

	return dataTemp;

}

const damn = initialGroupBy(json_data.rows);

 
document.getElementById("original").innerHTML = json_data.rows;
document.getElementById("output").innerHTML =JSON.stringify(damn);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div style="background:yellow; "id="original"></div>
<br><br>
<div style="background:red;" id="output"></div>

Я пытался изменить var на const во многих случаях.Я пропустил фундаментальный JavaScript случай здесь?

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

Поскольку ваше значение является объектом Array, когда вы сохраняете его во временной карте , вы фактически используете ссылку на исходную строку структуры данных.

Итак, в первом цикле forEach , где вы суммируете значения, которые вы фактически изменяете в исходной записи массива.

Решение довольно простое, просто клонируйте массив:

rowMap.set(key, row.slice());

Другая возможность - использовать другой массив для сохранения итогов.

Вот ваш код с исправлением.

var json_data = {"headers":["Month","Value","Number"],"rows":[["2018-10-01 00:00:00.0","one",209],["2018-09-01 00:00:00.0","one",274],["2018-09-01 00:00:00.0","five",183],["2018-10-01 00:00:00.0","five",164],["2018-09-01 00:00:00.0","four",214],["2018-10-01 00:00:00.0","four",192],["2018-09-01 00:00:00.0","three",128],["2018-10-01 00:00:00.0","three",125],["2018-09-01 00:00:00.0","two",199],["2018-10-01 00:00:00.0","two",169],["2018-09-01 00:00:00.0","seven",10541],["2018-10-01 00:00:00.0","seven",6139],["2018-10-01 00:00:00.0","six",169],["2018-09-01 00:00:00.0","six",233]]};

function initialGroupBy(rows) {
  const 
    rowMap = new Map(),
    result = [],
    dataTemp = [];
    
  // Iterate over the rows.
  rows.forEach(row => {
  
    const
      // Create a key, it is the first elements joined together.
      key = row.slice(0,1).join();
      
    // Check if the Map has the generated key...
    if (rowMap.has(key)) {
      // The map has the key, we need to add up the values
      const
        // Get the value for the current key.
        storedRow = rowMap.get(key);
        // Add the value of the current row to the row in the map.
        storedRow[2] += row[2];
        
    } else {
      // The key doens't exist yet, add the row to the map.
      rowMap.set(key, row.slice());
    }

  });
  
  // Iterate over all the entries in the map and push each value with the
  // summed up value into the array.
  rowMap.forEach(value => {
    result.push(value);
  });
    

	for (i = 0; i < result.length; i++) 
	{
    var object2 = {"date": result[i][0].slice(0,7), "num": result[i][2]};
    dataTemp.push(object2);      
	}

	return dataTemp;

}

const damn = initialGroupBy(json_data.rows);

 
document.getElementById("original").innerHTML = json_data.rows;
document.getElementById("output").innerHTML =JSON.stringify(damn);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div style="background:yellow; "id="original"></div>
<div style="background:red;" id="output"></div>
0 голосов
/ 12 октября 2018

Здесь применяется другая логика, и результат удобен:

var json_data = {"headers":["Month","Value","Number"],"rows":[["2018-10-01 00:00:00.0","one",209],["2018-09-01 00:00:00.0","one",274],["2018-09-01 00:00:00.0","five",183],["2018-10-01 00:00:00.0","five",164],["2018-09-01 00:00:00.0","four",214],["2018-10-01 00:00:00.0","four",192],["2018-09-01 00:00:00.0","three",128],["2018-10-01 00:00:00.0","three",125],["2018-09-01 00:00:00.0","two",199],["2018-10-01 00:00:00.0","two",169],["2018-09-01 00:00:00.0","seven",10541],["2018-10-01 00:00:00.0","seven",6139],["2018-10-01 00:00:00.0","six",169],["2018-09-01 00:00:00.0","six",233]]};


function groupBy(accumulator, item) {
const [date,extra,value] = item;

const key = date.slice(0,7);

if(!accumulator[key]){
accumulator[key] = 0
}

accumulator[key] += value;
return accumulator;

}

var damn = json_data.rows.reduce(groupBy,{});

damn = Object.keys(damn).map(function(key){
return {date: key, Value: "Total", num: damn[key]};
})

document.getElementById("original").innerHTML = json_data.rows;
document.getElementById("output").innerHTML =JSON.stringify(damn);
<div style="background:yellow; "id="original"></div>
<div style="background:red;" id="output"></div>
0 голосов
/ 12 октября 2018

A) Объявление const создает доступную только для чтения ссылку на значение.Это не означает, что значение, которое оно содержит, является неизменным -> Ссылка

B) Ваша проблема в том, что вы фактически редактируете исходный объект в функции initialGroupBy.Может быть, этот ответ будет полезен.

...