2016-03-03 4 views
3

У меня есть массив, как показано ниже. В моем реальном случае у него тысячи объектов.Подсчитайте число в массиве данных javascript

var data = [ 
    {type:'A',time:'2009'}, 
    {type:'A',time:'2009'}, 
    {type:'A',time:'2009'}, 
    {type:'A',time:'2009'}, 
    {type:'B',time:'2009'}, 
    {type:'B',time:'2009'}, 
    {type:'B',time:'2009'}, 
    {type:'C',time:'2009'}, 

    {type:'A',time:'2014'}, 
    {type:'A',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'C',time:'2014'}, 
    {type:'C',time:'2014'} 
]; 
var validTime = ['2009', '2014']; 
var typeArr = ['A','B','C']; 

Я хочу, чтобы преобразовать «data» массив с «newData», которая вычисляет количество каждого типа в каждом году.

var newData = [ 
    {time:'2009', A:4, B:3, C:1}, 
    {time:'2014', A:2, B:3, C:2} 
] 

Это то, что я сделал до сих пор. Я не знаю, что делать на следующем шаге. Я думаю, что я ухожу далеко от правильного подхода. Обычно я использую R для обработки данных и просто забираю javascript на пару недель. Может ли кто-нибудь вести меня, как это сделать, или любые веб-ресурсы с подобной проблемой будут очень полезны !! Спасибо!

И оцените, если вы могли бы добавить комментарии в свой ответ!

var arr1 = []; 
for (i = 0; i < validTime.length; i++) { 
    for (s = 0; s < typeArr.length; s++) { 
      var count = 0; 
      for (j = 0; j < data.length; j++) { 
       if (data[j]['time'] == validTime[i] && data[j]['type'] == typeArr[s]){ 
          count++;               
         } 
        } 
          arr1.push({ 
          'type': typeArr[s], 
          'x': validTime[i], 
          'y': count            
          }); 
       } 
      }; 
console.log(arr1); 

ответ

0

Вот один из способов сделать это:

var data = [ 
 
    { type:'A', time: '2009' }, 
 
    { type:'A', time: '2009' }, 
 
    { type:'A', time: '2009' }, 
 
    { type:'A', time: '2009' }, 
 
    { type:'B', time: '2009' }, 
 
    { type:'B', time: '2009' }, 
 
    { type:'B', time: '2009' }, 
 
    { type:'C', time: '2009' }, 
 

 
    { type:'A', time: '2014' }, 
 
    { type:'A', time: '2014' }, 
 
    { type:'B', time: '2014' }, 
 
    { type:'B', time: '2014' }, 
 
    { type:'B', time: '2014' }, 
 
    { type:'B', time: '2014' }, 
 
    { type:'C', time: '2014' }, 
 
    { type:'C', time: '2014' } 
 
]; 
 

 
var newData = { }; 
 
data.forEach(function(item) { 
 
    
 
    // if we don't already have a record for this time, create one 
 
    if (!newData[item.time]) { 
 
    newData[item.time] = { }; 
 
    } 
 
    
 
    // add 1 to the current value of this type for the given time  
 
    newData[item.time][item.type] = (newData[item.time][item.type] || 0) + 1; 
 
}); 
 

 
document.writeln('<pre>' + JSON.stringify(newData, null, 4) + '</pre>'); 
 

 

0

https://linqjs.codeplex.com/ использовать эту библиотеку, так что вам не придется писать свои собственные методы.

0

Вот простой способ, можно оптимизировать, если это будет необходимо (особенно, если вы можете гарантировать заказ типа, как в вашем примере)

var newData = []; 

for (var t = 0; t < validTime.length; t++) { 
    var acount = 0, bcount = 0, ccount = 0; 
    for (var i = 0; i < data.length; i++) { 
    if (data[i].time === validTime[t]) { 
     switch (data[i].type) { 
     case 'A': 
      acount++; 
      break; 
     case 'B': 
      bcount++; 
      break; 
     case 'C': 
      ccount++; 
      break; 
     } 
    } 
    } 
    newData.push({time: validTime[t], A: acount, B: bcount, C: ccount}); 
} 

jsfiddle

0
var data = [ 
    {type:'A',time:'2009'}, 
    {type:'A',time:'2009'}, 
    {type:'A',time:'2009'}, 
    {type:'A',time:'2009'}, 
    {type:'B',time:'2009'}, 
    {type:'B',time:'2009'}, 
    {type:'B',time:'2009'}, 
    {type:'C',time:'2009'}, 

    {type:'A',time:'2014'}, 
    {type:'A',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'C',time:'2014'}, 
    {type:'C',time:'2014'} 
]; 

var validTime = ['2009', '2014']; 
var typeArr = ['A','B','C']; 

// store the result inn object 
var out = data.reduce(function (hash, item) { 
    if (validTime.indexOf(item.time) >= 0) { 
    hash[item.time] = hash[item.time] || {}; 
    if (typeArr.indexOf(item.type) >= 0) { 
     hash[item.time][item.type] = hash[item.time][item.type] || 0; 
    } 
    hash[item.time][item.type] += 1; 
    } 
    return hash; 
}, {}); 

// convert result to array 
var value, type, time, arr = [], item; 
for (time in out) { 
    value = out[time]; 
    item = { 
     time: time 
    }; 
    for (type in value) { 
     item[type] = value[type]; 
    } 
    arr.push(item); 
} 

console.log(arr); // this is expected result (array) 
0

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

var data = [ 

{type:'A',time:'2009'}, 
    {type:'A',time:'2009'}, 
    {type:'A',time:'2009'}, 
    {type:'A',time:'2009'}, 
    {type:'B',time:'2009'}, 
    {type:'B',time:'2009'}, 
    {type:'B',time:'2009'}, 
    {type:'C',time:'2009'}, 

    {type:'A',time:'2014'}, 
    {type:'A',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'B',time:'2014'}, 
    {type:'C',time:'2014'}, 
    {type:'C',time:'2014'} 
]; 
var validTime = ['2009', '2014']; 
var typeArr = ['A','B','C']; 
var tempData = {}, newData = []; 
var item; 

for(var i = 0, len = data.length; i < len; i++) { 
    item = data[i]; 
    if(!tempData[item.time]) { 
    tempData[item.time] = {}; 
    } 

    tempData[item.time][item.type] = (tempData[item.time][item.type] || 0) + 1; 
} 

$.each(tempData, function(index, item) { 
    newData.push($.extend(item, {time: index})); 
}); 

console.log(newData); 

JS Fiddle https://jsfiddle.net/7bd1Lvb2/

0

Попробуйте с использованием for петли, for..in петли. Результирующий объект res должен содержать свойства, имеющие название объекта type; каждое свойство должно содержать два массива, первый массив должен быть отфильтрованные результаты type, второй массив должен содержать свойства time для каждого отфильтрованного результата, то есть 2009 и 2014

var data = [ 
 
    {type:'A',time:'2009'}, 
 
    {type:'A',time:'2009'}, 
 
    {type:'A',time:'2009'}, 
 
    {type:'A',time:'2009'}, 
 
    {type:'B',time:'2009'}, 
 
    {type:'B',time:'2009'}, 
 
    {type:'B',time:'2009'}, 
 
    {type:'C',time:'2009'}, 
 
    {type:'A',time:'2014'}, 
 
    {type:'A',time:'2014'}, 
 
    {type:'B',time:'2014'}, 
 
    {type:'B',time:'2014'}, 
 
    {type:'B',time:'2014'}, 
 
    {type:'B',time:'2014'}, 
 
    {type:'C',time:'2014'}, 
 
    {type:'C',time:'2014'} 
 
]; 
 

 
for (var i = 0, res = {}; i < data.length; i++) { 
 
    if (res[data[i].type] === undefined) { 
 
    if (!Array.isArray(res[data[i].type])) { 
 
     res[data[i].type] = []; 
 
     res[data[i].type].push(data[i]) 
 
    } else { 
 
     res[data[i].type].push(data[i]) 
 
    } 
 
    } else { 
 
    res[data[i].type].push(data[i]) 
 
    } 
 
} 
 

 
for (var prop in res) { 
 
    res[prop] = [res[prop], {2009:[], 2014:[]}]; 
 
    res[prop].forEach(function(value) { 
 
    for (var p in res[prop][1]) { 
 
     res[prop][1][p] = res[prop][0].filter(function(v) { 
 
     return v["time"] === p 
 
     }) 
 
    } 
 
    }) 
 
} 
 

 
document.querySelector("pre").textContent = JSON.stringify(res, null, 2)
<pre> 
 

 
</pre>

0

Наконец-то я получил рабочий ответ. Для меня это было отличным упражнением.

Код, который у вас есть, возвращает массив из 6 объектов.

{"type":"A","x":"2009","y":4} 
{"type":"B","x":"2009","y":3} 
{"type":"C","x":"2009","y":1} 
{"type":"A","x":"2014","y":2} 
{"type":"B","x":"2014","y":4} 
{"type":"C","x":"2014","y":2} 

, как видно из https://jsfiddle.net/aa15y7n0/

результатов вы хотите это массив с одним объектом на строку в validTime массиве. Каждый из этих объектов имеет метки, найденные в typeArr.

Я создал результирующий массив следующим образом:

var arr2 = []; 
//start by creating the array with the corect number of objects (2) 
for(var i = 0; i < validTime.length; i++) { 
    arr2.push({ 
    'time': validTime[i] 
    }); 
} 
//append onto those two objects the typeArr objects. 
for(var i=0;i<arr2.length;i++){ 
    for(var j=0;j<typeArr.length;j++){ 
    var thisObj = arr2[i]; 
    var thisProp = typeArr[j]; 
    thisObj[thisProp] = 0; 
    } 
} 
//modify the values to increase the counters 
for(var i=0;i<data.length;i++){ 
    for(var j=0;j<arr2.length;j++){ 
    if(data[i].time == arr2[j].time){ 
     //increase arr2[j].type count by 1. 
     var thisDataObjType = data[i].type; 
     arr2[j][thisDataObjType] += 1; 
    } 
    } 
} 

Вы можете увидеть результаты на https://jsfiddle.net/aa15y7n0/1/

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