2016-02-28 2 views
0

Это, наверное, что-то действительно глупое, что я слишком задумываюсь или просто не думаю о себе (бодрствовал почти 30 часов, что более чем вероятно).Зацикливание массива объектных литералов и сопоставимых клиентов

У меня есть массив «продаж», смотрите ниже:

let sales = [ 

    { 
     amount: 100, 
     customerName: "Johan" 
}, 
    { 
     amount: 262, 
     customerName: "James" 
}, 
    { 
     amount: 42, 
     customerName: "Fraser" 
}, 
    { 
     amount: 983, 
     customerName: "Calum" 
}, 
    { 
     amount: 246, 
     customerName: "Johan" 
} 
, 
    { 
     amount: 873, 
     customerName: "James" 
} 
, 
    { 
     amount: 210, 
     customerName: "Fraser" 
}, 
    { 
     amount: 68, 
     customerName: "Calum" 
} 


]; 

То, что я пытаюсь сделать, это цикл по массиву и вместо 2 записей для каждого клиента, я хотел бы 1 запись, кроме общая сумма должна составлять все суммы, связанные с этим клиентом, вместе взятые.

Я попытался использовать sales.forEach, а затем нажав значения в новый массив ... это просто сделал тот же массив снова .. в основном.

Я также пробовал использовать sales.reduce, но мой вывод не сделал то, что я описал выше, вместо этого он по-прежнему сделал 2 записи, за исключением того, что вторая запись добавила итоговые значения.

У меня был взгляд вокруг и даже здесь, нет ничего точно как то, что я ищу.

Я хочу сделать это в чистом javascript.

Если вам нужны разъяснения, просто спросите в комментариях, а не отметьте!

+0

вы хотите массив в качестве результата или объект? –

+0

Не могли бы вы показать свое предпринятое (нерабочее) решение и показать полученный результат и желаемый результат? –

ответ

2

Есть несколько способов сделать это, вот один с уменьшить:

sales.reduce((newSales, item) => { 
    const existingItem = newSales.find(el => el.customerName === item.customerName); 
    // it exists, add to the existing one 
    if (existingItem) { existingItem.amount += item.amount; } 
    // it doesn't exist, add the one we have 
    else { newSales.push(item); } 
    return newSales; 
}, []); // start with an empty array. 
+0

Я получаю сообщение об ошибке в моей консоли, когда я console.log newSales, он говорит: «TypeError: Невозможно прочитать свойство« найти неопределенный »? – SkullDev

+0

[Array.prototype.find] (https://devdocs.io/javascript/global_objects/array/find) поддерживается в последних версиях Chrome и Firefox, но не в IE. Это не очень сложно использовать '.filter() [0]' или '.indexOf()' вместо этого. –

0

Вы можете попробовать что-то вроде этого:

var sales = [ 
 
    { amount: 100, customerName: "Johan"}, 
 
    { amount: 262, customerName: "James"}, 
 
    { amount: 42, customerName: "Fraser"}, 
 
    { amount: 983, customerName: "Calum"}, 
 
    { amount: 246, customerName: "Johan"}, 
 
    { amount: 873, customerName: "James"}, 
 
    { amount: 210, customerName: "Fraser"}, 
 
    { amount: 68, customerName: "Calum"}]; 
 

 

 
var _tmp = {}; 
 

 
// Sort array using customer name 
 
sales.sort(function(a,b){ 
 
    if(a.customerName < b.customerName) return -1; 
 
    if(a.customerName > b.customerName) return 1; 
 
    return 0; 
 
}) 
 
    // Find and remove duplicate entries 
 
.forEach(function(item){ 
 
    _tmp[item.customerName] = (_tmp[item.customerName] || 0) + item.amount; 
 
}); 
 

 
// Create final result 
 
var result = []; 
 
Object.keys(_tmp).forEach(function(key){ 
 
    result.push({"customerName":key, "amount": _tmp[key]}); 
 
}); 
 

 
document.write("<pre>" + JSON.stringify(result,0,4) + "</pre>")

0
var sales = [{ 
    amount: 100, 
    customerName: "Johan" 
}, { 
    amount: 262, 
    customerName: "James" 
}, { 
    amount: 42, 
    customerName: "Fraser" 
}, { 
    amount: 983, 
    customerName: "Calum" 
}, { 
    amount: 246, 
    customerName: "Johan" 
}, { 
    amount: 873, 
    customerName: "James" 
}, { 
    amount: 210, 
    customerName: "Fraser" 
}, { 
    amount: 68, 
    customerName: "Calum" 
}]; 

var reduced_sales = sales 
    .reduce(function (prev, curr) { 
    var prev_amount = prev[curr.customerName] || 0 
    prev[curr.customerName] = prev_amount + curr.amount 
    return prev; 
    }, {}); 

var sales_final = []; 
for (var prop in reduced_sales) { 
    sales_final.push({ 
     amount: reduced_sales[prop], 
     customerName: prop 
    } 
); 
} 

console.log(sales_final); 
0

Вы можете используйте петлю for..in, Array.prototype.forEach()

var names = [], amounts = [], res = []; 
for (var prop in sales) { 
    var n = sales[prop].customerName; 
    var a = sales[prop].amount; 
    var index = names.indexOf(n); 
    if (index == -1) { 
    names.push(n); 
    amounts.push(a); 
    } else { 
    amounts[index] += a; 
    } 
}; 

names.forEach(function(name, key) { 
    // populate `res` array with results contained in `names`, `amounts` 
    res[key] = {customerName:name, amount:amounts[key]} 
}); 
0

Возможно, самый простой способ, чтобы преобразовать карту

var salesByCustomerName = {}; 
for (var i = 0; i < sales.length; i++) 
{ 
    var sale = sales[i], customerName = sale.customerName; 
    salesByCustomerName[customerName] = 
      (salesByCustomerName[customerName] || 0) + sale.amount; 
} 

// Firebug prints: Object { Johan: 346, James: 1135, Fraser: 252, Calum: 1051 } 
console.log(salesByCustomerName); 
+0

Это объект, а не [Карта] (https://devdocs.io/javascript/global_objects/map) –

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