JavaScript:基于不同的对象数组编译对象数组

时间:2014-02-19 16:59:24

标签: javascript arrays

我有一个invoices数组,我希望根据值monthlyIncome编译一个invoiceMonth的有序列表(例如" 2014年2月和#34;)。 monthlyIncome数组必须存储月份名称和该月的收入,即

monthlyIncome = [
    { name: 'January 2014', income: 1000}, 
    { name: 'February 2014', income: 1500 } 
    ...
];

基本上我需要的是一个更深层次的"排序indexOf(val),检查val是否在monthlyIncome的任何对象的指定属性中,然后返回该索引。在此示例中,我使用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 
        });
    }
}

唯一的问题是我不确切地知道如何写deepIndexOf。此外,我怀疑在JavaScript中有一种更好的方法,而不是我所概述的方式。

2 个答案:

答案 0 :(得分:0)

您可以执行以下操作以返回与数组中的属性值匹配的第一个索引:

Live Demo

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'));

然后只需在代码中更新此行:

var index = monthlyIncome.deepIndexOf(invoices[i].invoiceMonth, 'name');

var index = indexByPropertyVal(monthlyIncome, 'name', invoices[i].invoiceMonth);


您还可以扩充Array的原型以包含函数:

Live Demo

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; 
};

然后只需在代码中更新此行:

var index = monthlyIncome.deepIndexOf(invoices[i].invoiceMonth, 'name');

var index = monthlyIncome.indexByPropertyVal('name', invoices[i].invoiceMonth);

答案 1 :(得分:0)

您的deepIndexOf函数可以是:

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'));

或者,要编译的整个代码可以是:

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
});