1

Использование методов функционального программирования javascript (например, map/reduce), как бы заполнить/подсчитать поле statusarr1 и преобразовать его в массив объектов с ключом/значением в arr2.Совокупность и преобразование массива объектов

arr1 = [ 
    {'task':'do something 1', 'status':'done'} , 
    {'task':'do something 2', 'status':'done'} , 
    {'task':'do something 3', 'status':'pending'} , 
    {'task':'do something 4', 'status':'done'} 
]; 

// Aggregate arr1 `status` field and transform to: 

arr2 = [ 
    {key:'done', value: 3}, 
    {key:'pending', value: 1} 
]; 

Вот мой WIP частичное решение, которое обрабатывает только агрегация часть. Мне все еще нужна часть преобразования.

var arr2 = arr1.map(function(item) { 
    return item.status; 
    }).reduce(function(acc,curr,idx){ 
    if(acc[curr] === undefined) acc[curr] = 1; 
    else acc[curr] += 1; 
    return acc; 
    }, []); 
+1

Я бы просто сделать [это] (https://jsfiddle.net/ocqnnmw3/1/), но не уверен, что это достаточно "функциональный". – adeneo

+0

Ваше решение не дает ожидаемого ответа. Или предоставленный ответ неверен. – Kiril

+0

Я считаю, что @Kiril прав, опубликованный код производит '[done: 3, pending: 1]', или, другими словами, обрабатывает массив как объект и не возвращает ожидаемый результат? – adeneo

ответ

0

Вот самый функциональный способ, которым я мог придумать. Это включает в себя как агрегацию и ваше желаемое преобразование:

var arr2 = Object.keys(arr2 = arr1.map(function(item) { 
    return item.status; 
}).reduce(function(acc,curr){ 
    acc[curr] = acc[curr] + 1 || 1; 
    return acc; 
}, [])).map(function(item){ 
    return {key: item, value: arr2[item]} 
}); 
+0

Alex, очень красиво сделано. Единственное, что я сделаю, это мой собственный код - консолидировать строки 4 и 5 в тройной 'acc [curr] === undefined? acc [curr] = 1: acc [curr] + 1; ' – jboothe

+0

@jboothe хорошая точка! Я тоже думал троятельно, но придумал немного более компактное решение, что вы думаете? –

+0

Nifty. undefined + 1 или 1. – jboothe

0

Вы можете попробовать Array.prototype.forEach(). Также вместо использования массива вы можете использовать объект. Это позволит вам сэкономить время, чтобы найти счет определенного статуса.

arr1 = [ 
 
    {'task':'do something 1', 'status':'done'} , 
 
    {'task':'do something 2', 'status':'done'} , 
 
    {'task':'do something 3', 'status':'pending'} , 
 
    {'task':'do something 4', 'status':'done'} 
 
]; 
 

 
var result = {}; 
 
arr1.forEach(function(item){ 
 
    if(!result[item.status]) 
 
    result[item.status] = 0; 
 
    
 
    result[item.status]++; 
 
}); 
 
console.log(result);

0

Поскольку вы сохраняете выходное значение как массив, вы должны проверить переждать состояние ключа присутствует или нет. Если присутствует, увеличьте его значение.

arr2 = []; 
arr1.forEach(function(item){ 
    var keyPresent = false; 
    for(var i = 0, len = arr2.length; i < len; i++) { 
     if(arr2[ i ].key === item.status){ 
     keyPresent = true; 
     arr2[ i ].value++ 
     } 
    } 
    if(!keyPresent){ 
    arr2.push({key: item.status , value : 1}) 
} 

Выходной сигнал задается

arr2 = [ 
    {key:'done', value: 3}, 
    {key:'pending', value: 1} 
]; 
Смежные вопросы