从Javascript中的数组数组中获取不同的值
我的数据格式如下从Javascript中的数组数组中获取不同的值,javascript,knockout.js,underscore.js,lodash,Javascript,Knockout.js,Underscore.js,Lodash,我的数据格式如下 var data= [['typeName', 'valueName'], ['type1', 'value1'], ['type1', 'value2'],['type2', 'value3'],['type2', 'value4']] 我希望将上述数据转换为以下数据 var resultdata=[{'typeName':'type1','valueName':['value1','value2']}, {'typeName':'type2','value
var data= [['typeName', 'valueName'], ['type1', 'value1'],
['type1', 'value2'],['type2', 'value3'],['type2', 'value4']]
我希望将上述数据转换为以下数据
var resultdata=[{'typeName':'type1','valueName':['value1','value2']},
{'typeName':'type2','valueName':['value3','value4']}]
基本上,我选择不同的“typeName”值,然后按“typeName”值对“valueName”值进行分组
我最好只使用knockoutjs、lodash或下划线,因为我的soln已经在使用它们,但我也愿意使用其他解决方案
衷心感谢您的帮助
鉴于结果,感谢您:
var resultdata=[
{'typeName':'type1'},{'valueName':['value1','value2']},
{'typeName':'type2'},{'valueName':['value3','value4']}
]
我将把类别称为“typeName”,将项目称为“valueName”
由于原始数据如下所示:
var data= [
['typeName', 'valueName'],
['type1', 'value1'],
['type1', 'value2'],
['type2', 'value3'],
['type2', 'value4']
]
很明显,有一种模式。第一行数据是我们将用作类别和项目标签的数据。所有剩余数据表示类别和项目中使用的值
第一步是提取标签:
var categoryLabel = data[0][0];
var itemLabel = data[0][1];
接下来,需要确定唯一类别,因此我们将使用reduce构建一个唯一类别数组:
var categories = data
.filter(function(row, i) { return i > 0 }) // remove the labels
.reduce(function(arrCategories, currRow) {
// Add the current rows' category if it doesn't already exist
var currCategory = currRow[0];
if (arrCategories.indexOf(currCategory) === -1) {
return arrCategories.concat(currCategory);
}
return arrCategories;
}, [])
现在您已经有了一组类别,只需对每个类别进行迭代即可找到属于它的所有项目:
var valuesByCategory = {};
categories.forEach(function(category) {
// find all the data items that match the category
var items = data
.filter(function(row) { return row[0] === category; })
.reduce(function(arrItems, currRow) {
var currItem = currRow[1];
if (arrItems.indexOf(currItem) === -1) {
return arrItems.concat(currItem);
}
return arrItems;
}, []);
valuesByCategory[category] = items;
});
现在,所有数据都已解析出来,唯一要做的就是构建结果数组:
var resultdata = [];
// iterate through each of the categories
categories.forEach(function(category) {
// using the category label, output an object with the label and category
var categoryObj = {};
categoryObj[categoryLabel] = category;
resultdata.push(categoryObj);
// Next, create a items object containing all the values
var itemsObj = {};
itemsObj[itemLabel] = valuesByCategory[category];
resultdata.push(itemsObj);
}
就这样:)
最好的部分是您不需要任何外部库。这都是ES2015 javascript 我认为使用下划线的解决方案应该可以做到:
var result= _.chain(data)
.rest()
.groupBy( value => value[0])
.map( (value,key) => ({ [data[0][0]]: key, [data[0][1]]: _.map(value, val => val[1])}))
.value();
此解决方案用于跳过数据数组中的第一项(类型描述符)。然后通过数组中的第一个值(类型)对数组进行排序,映射使用es6表示法以所需形式返回分组。以下是Groff Bunnies解决方案的lodash版本:
var data= [['typeName', 'valueName'], ['type1', 'value1'], ['type1', 'value2'],['type2', 'value3'],['type2', 'value4']]
var names = data[0]
var values = _.tail(data)
console.log(JSON.stringify(
_(values)
.groupBy(0)
.map( (value, key) => ({ [names[0]]: key, [names[1]]: _.map(value, 1)}) )
.value()
))
从您的结构中创建结果数据的标准是什么?衷心感谢您的帮助,特别是解释,您给出的答案与我首先提出的问题相匹配,结果数据结构为[{'typeName':'type1'},{'valueName':['value1','value2']},{'typeName':'type2'},{'valueName':['value3','value4']}],但后来我将结构更新为[{'typeName':'type1','valueName':['value1','value2']},{'typeName':'type2','valueName':['value3','value4']}],我相信您在mychanges之前就开始了,如果您更改您的答案,我会很感激的,但是您已经选择了答案,所以没有意义:)好的,明白了..var categoryObj={};categoryObj[categoryLabel]=category;categoryObj[itemLabel]=valuesByCategory[category];resultdata.push(categoryObj);如果我将数据更改为[['typeName'、'valueName'、'extraName']、['type1'、'value1'、'extra1']、['type1'、'value2'、'extra2']、['type2'、'value3'、'extra3']、['type2'、'value4'、'extra4']],valuename具有extraname值,是否可以确保valuename始终具有第二个字段值。此外,是否可以不在映射中硬编码typename和valuename..调整代码以使用第一个数据项中的字符串作为结果的属性名,并使用第二个valuename解决方案!我推荐一些解决方案注释,因为代码在阅读时不太容易理解。