2015-04-27 5 views
1

Используя Javascript, я пытаюсь преобразовать некоторые данные JSON в формат, используемый в базовой линейной диаграмме Highcharts.Преобразование данных JSON в формат в базовой линейной диаграмме Highcharts

То, что я должен начать с:

originalArray = [ 
    ['valueA', 1], 
    ['valueA', 0], 
    ['valueB', 9], 
    ['valueB', 9], 
    ['valueB', 3], 
    ['valueC', 11] 
] 

А что я пытаюсь создать с помощью выше:

desiredArray = [{ 
     name: 'valueA', 
     data: [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
    }, { 
    name: 'valueB', 
    data: [0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0] 
    }, { 
    name: 'valueC', 
    data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] 
    }] 

Для некоторого дополнительного контекста 0-11 в originalArray[i][1] ссылки в месяц (0 = январь), а desiredArray - это список уникальных имен и количество их вхождений по месяцам.

До сих пор, я могу:

  • Преобразование данных в новый массив объектов
  • Для каждого уникального имени в originalArray
    • Создать новый объект в desiredArray, и установить атрибут name
    • Добавить атрибут data, который содержит пустой массив

Но тогда я запускаю в беду, и не могу понять, как:

  • Петля через originalArray
    • Если имя в originalArray совпадает с именем в desiredArray
      • Увеличение счетчика в массиве seriesArray[i].data, используя значение originalArray[i][1] как индекс (он всегда равен 0-11).

Вот я и спрашиваю:

  1. Что хороший способ итерации по моим originalArray, совпадает уникальные значения, и затем действует только на тех матчах нажать на desiredArray.
  2. Какой самый лучший способ, чтобы увеличить счетчики в desiredArray[i].data

Я открыт для использования библиотек, таких как underscore.js. Пытались понять это на пару дней, так что почти все идет в пределах Javascript.

+0

Кстати, на счет в вашей записи в desiredArray VALUE млрд ошибается, я думаю, что ... должен быть 1 в данных [3]? –

+0

@SMcCrohan Хороший улов, обновленный –

+0

Где код? –

ответ

2

Обновлено с помощью правильной инициализации массива.

var max = originalArray.reduce(function(p,c){return Math.max(p,c[1]);},0); 

var initSums = function(size) { 
    var arr = new Array(size); 
    for (var i=0;i<size;i++) 
     arr[i]=0; 
    return arr; 
} 

var map = originalArray.reduce(function(sums,val){ 
    if (!sums.hasOwnProperty(val[0])) { 
     sums[val[0]] = initSums(max+1); 
    } 
    sums[val[0]][val[1]]++; 
    return sums; 
},{}); 

var desiredArray = Object.keys(map).map(function(key) { 
    return {name: key, data: map[key]}; 
}); 

Что мы делаем здесь, это многоэтапный процесс:

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

  2. Используйте объект для объединения подсчетов (используя Array.reduce()).

  3. Преобразование объекта и его свойств в массив объектов с именем/данными (с использованием Array.map).

+0

Просто примечание - поскольку я понимаю вопрос, не только поиск 'max' ненужен, но и на самом деле вреден. Массив всегда должен иметь длину 12, по одному для каждого месяца. Если 'valueC' был удален из' originalArray', результат будет неправильным. –

+0

Хм, согласился. Не уверен, что это было добавлено к вопросу позже или если я прочитал его, но если массивы надежно всегда одного размера, то да, эта проверка является посторонней. –

+0

Нет, это было с самого начала. Я должен был прокомментировать, возможно, вместо того, чтобы просто предоставить мое решение. @SeanConnelly может вернуться, если он найдет, что это не сработает. :-) –

0

Редактировать: улучшение на решение S McCochran, в пропуске постороннее поиск максимального значения в originalArray, так как всегда должно быть 12 элементов каждого массива данных, по одному в месяц.

function formatForHighcharts(array) { 

    // Create a map from value name to array of month counts 
    var map = originalArray.reduce(function(sums, pair) { 
    var key = pair[0], val = pair[1]; 

    if(!(key in sums)) 
     sums[key] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 

    // val is the month index, which corresponds directly to array index, so increase that 
    sums[key][val]++; 

    return sums; 
    }, {}); 

    // Map the object to an array of { name: ..., data: ... } pairs 
    var formatted = Object.keys(map).map(function (key) { 
    return { name: key, data: map[key] }; 
    }); 

    return formatted; 
} 

Использование:

var desiredArray = formatForHighcharts(originalArray); 
Смежные вопросы