我目前在从数组中获取不同的值列表时遇到一些问题。
我正在寻找的是能够以“
”的形式给出一些干扰值的东西我有以下项目数组
[{"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
提供了一个项目。
答案 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
是否具有属性abc
,def
等。此条件将始终为true,因为数组不具有此类属性。您通常会将带有 numeric 属性的属性添加到数组中,例如像你一样.push
。
对象可以具有任意属性。
现在关于:
test["office"][office] += 1;
这将访问数组的属性office
(不存在),然后访问属性abc
,def
等(当然也不存在,因为{ {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}