JavaScript:通过列值索引对象
我有一个如下所示的表数组:JavaScript:通过列值索引对象,javascript,arrays,object,multidimensional-array,indexing,Javascript,Arrays,Object,Multidimensional Array,Indexing,我有一个如下所示的表数组: tablearray = [ {'column1': 1, 'column2': 1, 'column3': 1, 'column4': 2}, {'column1': 1, 'column2': 2, 'column3': 3, 'column4': 4}, {'column1': 2, 'column2': 0, 'column3': 4, 'column4': 6} ] 我试图创建一个函数,它接受表数组和列名数组,并创建一个新对象,该对
tablearray =
[
{'column1': 1, 'column2': 1, 'column3': 1, 'column4': 2},
{'column1': 1, 'column2': 2, 'column3': 3, 'column4': 4},
{'column1': 2, 'column2': 0, 'column3': 4, 'column4': 6}
]
我试图创建一个函数,它接受表数组和列名数组,并创建一个新对象,该对象由列值索引。所以
newObject = indexByColumnValues(tablearray, ['column1', 'column2']);
应该会导致像这样的对象
newObject =
{
1:
{
1: {'column1': 1, 'column2': 1, 'column3': 1, 'column4': 2},
2: {'column1': 1, 'column2': 2, 'column3': 3, 'column4': 4}
}
2:
{
0: {'column1': 2, 'column2': 0, 'column3': 4, 'column4': 6}
}
}
所以
如果已知列名数组中的列数(['column1','column2']),则解决方案并不难。但是,如果我允许这个数组中有任意数量的列名,那么由于存在不确定递归,这将变得更加困难
newObject[tablearray[columnNameArray[0]][tablearray[columnNameArray[1]][tablearray[columnNameArray[2]]...
这里有一个尝试。我尝试使用指针指向newObject数组的维度深度。首先,指针=newObject。然后指针=新对象[…[0]]。然后点=新对象[…[0][…[1]]。等等这会正确地构建对象,但是我没有办法为newObject[…[0]]…[…[k]]赋值
function indexByColumnValues(object, columnNameArray)
{
var newObject = {};
for(i in object)
{
var index=[];
for(j in columnNameArray)
{
index.push(object[i][columnNameArray[j]]);
}
var pointer = newObject;
for(j in index)
{
if(pointer[index[j]] == undefined)
{
pointer[index[j]] = {};
}
pointer = pointer[index[j]];
}
//now pointer points to newObject[index[0]][index[1]]...[index[k]]
//but I need to set newObject[...] above to be object[i]. How?
//pointer = object[i]; //won't work
}
return newObject;
}
这里有任何帮助或提示都很好。谢谢。您提到了递归,但在代码中没有使用它。这是一个典型的情况,递归是正确的工具。下面是一个实现:
function indexByColumnValues(table, cols) {
// get the column we're indexing
var col = cols[0],
index = {},
x, val;
// find all values
for (x=0; x<table.length; x++) {
val = table[x][col];
// add to index if necessary
if (!index[val]) index[val] = [];
// push this row
index[val].push(table[x]);
}
// recurse if necessary
if (cols.length > 1) {
for (x in index) {
if (index.hasOwnProperty(x)) {
// pass the filtered table and the next column
index[x] = indexByColumnValues(
index[x],
cols.slice(1)
);
}
}
}
return index;
}
输出:
{
"1":{
"1":[
{"column1":1,"column2":1,"column3":1,"column4":2}
],
"2":[
{"column1":1,"column2":2,"column3":3,"column4":4}
]
},
"2":{
"0":[
{"column1":2,"column2":0,"column3":4,"column4":6}
]
}
}
JSFIDLE:我不知道您是想使用库还是想从自己的代码中学习(这很有帮助),但是下划线.js有
\uwg.groupBy
,这正是您想要的。结果中的内部对象不应该是一个数组,其中包含每个对象,每个对象都有一个匹配的列一个值吗?@jfriend00出于我的目的,由于我希望使用的列值组合是唯一的,因此不需要内部数组。@pimvdb谢谢,我会检查它。这非常有效。非常感谢。我让它变得比需要的更难;使用递归函数肯定有帮助。
indexByColumnValues(tablearray, ['column1','column2']);
{
"1":{
"1":[
{"column1":1,"column2":1,"column3":1,"column4":2}
],
"2":[
{"column1":1,"column2":2,"column3":3,"column4":4}
]
},
"2":{
"0":[
{"column1":2,"column2":0,"column3":4,"column4":6}
]
}
}