0

我目前在从数组中获取不同的值列表时遇到一些问题。

我正在寻找的是可以让我以表格形式计算不同值的东西

我有以下项目数组

[{"Office":"abc", "Name":"ABC", "Total":0},
{"Office":"def", "Name":"DEF", "Total":11},
{"Office":"def", "Name":"DEF", "Total":1},
{"Office":"ghi", "Name":"GHI", "Total":1111}]

我正在寻找以下输出,它是一个不同的办公室列表,其中包含每个办公室的实例数。

[
    {"office":"abc","count":1},
    {"office":"def","count":2},
    {"office":"ghi","count":1}
]

我尝试过的以下是

ko.utils.arrayForEach(officeLines, function (item, indx)
{
    var office = item.Office;
    if (test[office] == null)
    {
        test.push({ office: office, count: 1 });
    }
    else
    {
        test["office"][office] += 1;
    }
});

但这给了我Office原始数组中的每个项目。

4

5 回答 5

6

看起来您需要字典或哈希来创建唯一办公室列表,然后将其转换为最终结果的数组。

在您的代码中,您将数组语法与关联数组(文字对象)语法混淆了。

差异示例:

var array = [];
array[0] = { bar: 'foo' }; // note the numeric index accessor/mutator

var obj = {};
obj['property'] = { bar: 'foo' }; // the brackets serve as a property accessor/mutator

要修复您的代码:

var hash = {}; // object literal
ko.utils.arrayForEach(officeLines, function (item, indx) {
    var office = item.Office;
    if (!hash.hasOwnProperty(office)) {
        hash[office] = { office: office, count: 1 };
    }
    else {
        hash[office].count++;
    }
});

// make array
var test = [];
for(var office in hash)
    if(hash.hasOwnProperty(office))
        test.push(hash[office]);
于 2013-06-26T15:17:02.673 回答
2

您似乎在这里混合了数组和对象。

if (test[office] == null)

将测试数组 test是否具有属性abcdef。此条件将始终为真,因为数组没有此类属性。您通常将具有数字属性的属性添加到数组中,例如,.push您也可以这样做。

另一方面,对象可以具有任意属性。

现在关于:

test["office"][office] += 1;

这将访问office数组的属性(不存在),然后访问属性abc,def等(当然也不存在,因为test.office一开始就不存在)。


您必须决定是要test成为数组还是对象。
如果您选择一个对象,聚合数据将更容易,因为您可以轻松测试对象属性的存在。
如果你想要一个数组,你可以将对象转换为数组,或者如果你从一开始就使用一个,你必须遍历数组的元素并找到正确的元素。该解决方案不太可取,因为运行时将是O(n^2).

目的:

var test = {};

ko.utils.arrayForEach(officeLines, function (item, indx) {
    var office = item.Office;
    if (!test[office]) {
        hash[office] = 1
    }
    else {
        hash[office] += 1;
    }
});

test然后看起来像:

{
    abc: 1,
    def: 2,
    ghi: 1
}

并且很容易根据需要创建一个数组。

大批:

var test = [];

ko.utils.arrayForEach(officeLines, function (item, indx) {
    var office = item.Office;
    for (var i = 0, l = test.length; i < l; i++) {
        if (test[i].office === office) {
            test[i].count += 1;
            return;
        }
    }
    test.push({office: office, count: 1});
});

我希望您已经可以从嵌套循环(for内部forEach)中看出这不是最佳解决方案。


进一步阅读材料:

于 2013-06-26T15:27:19.560 回答
0
var officeLines = [{"Office":"abc", "Name":"ABC", "Total":0},
                   {"Office":"def", "Name":"DEF", "Total":11},
                   {"Office":"def", "Name":"DEF", "Total":1},
                   {"Office":"ghi", "Name":"GHI", "Total":1111}];

var test = {};

for (office_idx in officeLines) {
    var office = officeLines[office_idx];
    if (test[office['Office']]) {
        test[office['Office']]['count'] += 1;
    } else {
        test[office['Office']] = {office: office, count: 1};
    }
}
var results = []
for (office_id in test){
    results.push(test[office_id]);
}
于 2013-06-26T15:25:18.030 回答
0

这样的事情呢?

var test = {};
ko.utils.arrayForEach(officeLines, function (item, indx)
{
    var office = item.Office;
    if (typeof test[office] === "undefined")
    {
        test[office] = 1;
    }
    else
    {
        test[office]++;
    }
});
// back to array
var array = [];
for (var office in test) {
    array.push({ office: office, count: test[propertyName] });
}

我认为您可能不必转换回数组,因为您可能可以使用 $index 来获取办公室名称,然后使用 $data 在 knockoutjs 中的 foreach 中进行计数。

于 2013-06-26T15:15:13.050 回答
-1

与其将结果推送到数组中,不如将它们推送到对象中,如下所示:

var officeLines = [{"Office":"abc", "Name":"ABC", "Total":0},
{"Office":"def", "Name":"DEF", "Total":11},
{"Office":"def", "Name":"DEF", "Total":1},
{"Office":"ghi", "Name":"GHI", "Total":1111}];
var offices = {};
ko.utils.arrayForEach(officeLines, function (item, indx)
{
    var office = item.Office;
    if (!offices[office])
    {

        offices[office] = 1;
    }
    else
    {
        offices[office]++;
    }
});

document.write(JSON.stringify(offices)); // -> {"abc":1,"def":2,"ghi":1}

http://jsfiddle.net/zd5Db/

于 2013-06-26T15:08:26.820 回答