检查数组中是否存在密钥

时间:2013-06-26 15:05:39

标签: javascript json

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

我正在寻找的是能够以“

”的形式给出一些干扰值的东西

我有以下项目数组

[{"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提供了一个项目。

5 个答案:

答案 0 :(得分: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]);

答案 1 :(得分:2)

你好像在这里混合数组和对象。

if (test[office] == null)

将测试数组 test是否具有属性abcdef等。此条件将始终为true,因为数组不具有此类属性。您通常会将带有 numeric 属性的属性添加到数组中,例如像你一样.push

另一方面,

对象可以具有任意属性。

现在关于:

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

这将访问数组的属性office(不存在),然后访问属性abcdef等(当然也不存在,因为{ {1}}首先不存在。)


您必须决定是否希望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)看到这不是最佳解决方案。


进一步阅读材料:

答案 2 :(得分: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的计数。

答案 3 :(得分: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]);
}

答案 4 :(得分:-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/