I have an array of invoices
and I want to compile an ordered list of monthlyIncome
based on a value invoiceMonth
(eg "February 2014"). The monthlyIncome
array has to store the month name and the income for that month, ie
monthlyIncome = [
{ name: 'January 2014', income: 1000},
{ name: 'February 2014', income: 1500 }
...
];
Basically what I need is a "deeper" sort of indexOf(val)
, that would check if val
is in a specified property of any object of monthlyIncome
, and then return that index. In this example I use deepIndexOf(value, property)
.
for (var i=0; i<invoices.length; i++) {
var index = monthlyIncome.deepIndexOf(invoices[i].invoiceMonth, 'name');
if (index > -1) {
// month already exists in list, so add the total
monthlyIncome[index].income += invoice.total;
} else {
// month doesn't exist, so add it
monthlyIncome.push({
name: invoices[i].invoiceMonth,
income: invoices[i].total
});
}
}
The only problem is that I don't know exactly how I would write deepIndexOf
. Also, I suspect there is a better way to do this in JavaScript than the way I've outlined.
You can do the following to return the first index that matches a property value in your array:
function indexByPropertyVal(values, propName, propVal){
var i = 0,
count = values.length;
for(; i < count; i++){
if(values[i][propName] === propVal){
return i;
}
}
return -1;
}
monthlyIncome = [
{ name: 'January 2014', income: 1000},
{ name: 'February 2014', income: 1500 },
{ name: 'March 2014', income: 1500 } ,
{ name: 'April 2014', income: 1500 } ,
{ name: 'May 2014', income: 1500 }
];
alert(indexByPropertyVal(monthlyIncome, 'name', 'April 2014'));
alert(indexByPropertyVal(monthlyIncome, 'name', 'June 2014'));
Then just update this line in your code from:
var index = monthlyIncome.deepIndexOf(invoices[i].invoiceMonth, 'name');
to
var index = indexByPropertyVal(monthlyIncome, 'name', invoices[i].invoiceMonth);
You can also augment the prototype of the Array to include the function:
Array.prototype.indexByPropertyVal = function(propName, propVal){
var i = 0,
count = this.length;
for(; i < count; i++){
if(this[i][propName] === propVal){
return i;
}
}
return -1;
};
Then just update this line in your code from:
var index = monthlyIncome.deepIndexOf(invoices[i].invoiceMonth, 'name');
to
var index = monthlyIncome.indexByPropertyVal('name', invoices[i].invoiceMonth);
Your deepIndexOf function can be like:
function deepIndexOf(array, key, value) {
var obj;
for (var idx = 0; idx < array.length; idx++) {
var obj = array[idx];
if (obj[key] === value) {
return idx;
}
}
return -1;
}
var monthlyIncome = [{
name: 'January 2014',
income: 1000
}, {
name: 'February 2014',
income: 1500
}];
console.log(deepIndexOf(monthlyIncome, 'name', 'January 2014'));
console.log(deepIndexOf(monthlyIncome, 'name', 'February 2014'));
console.log(deepIndexOf(monthlyIncome, 'name', 'None 2014'));
Or, the entire code to compile can be like:
function compile(incomeList, invoice) {
var found = false;
for (var i = 0; i < incomeList.length && !found; i++) {
if (incomeList[i].name === invoice.invoiceMonth) {
incomeList[i].income += invoice.total;
found = true;
}
}
if (!found) {
incomeList.push({
name: invoice.invoiceMonth,
income: invoice.total
});
}
}
compile(monthlyIncome, {
invoiceMonth: 'January 2014',
total: 1000
});
compile(monthlyIncome, {
invoiceMonth: 'March 2014',
total: 1000
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.