检查键存在于数组中

Check Key Exists in Array

本文关键字:数组 存在 于数组 检查      更新时间:2023-09-26

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

我要找的是能给我一个形式的distict值的计数

我有以下项目阵列

[{"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;
    }
});

但这为原始数组中的每个CCD_ 1提供了一个单独的项。

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

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

差异示例:

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

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

if (test[office] == null)

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

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

现在关于:

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

这访问数组的属性office(不存在),然后访问属性abcdef等(当然也不存在,因为test.office最初并不存在)。


您必须决定Office0是一个数组还是一个对象
若您选择一个对象,聚合数据会更容易,因为您可以轻松地测试对象属性的存在
如果你想要一个数组,你可以将对象转换为数组,或者如果你从一开始就使用数组,你必须迭代数组的元素并找到合适的元素。该解决方案不太可取,因为运行时将是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});
});

我希望您已经从嵌套循环(forEach中的for)中看到,这不是一个最佳解决方案。


进一步阅读材料:

  • MDN-使用对象
  • 雄辩javascript.net-数据结构:对象和数组

这样的东西怎么样?

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来获取办公室名称,然后在knockoutjs中的foreach中使用$data来获取计数。

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

与其将结果推送到数组,不如将它们推送到这样的对象:

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/