我有一系列对象oDataSet
和aProperties
对象,我想匹配aPropertis
和In {{}中的相同的值1}}并创建 aSelectedDataSet ,开头是一个空对象
如何建议在JS / Jquery
中执行此操作注意:在循环/解决方案中不应该有任何硬编码 属性来进行匹配 aProperties包含此值,但它可以更改(当然应该在oData对象中匹配...)
澄清以下是如何构建对象的示例
http://jsfiddle.net/4rh6tt25/5/
这是输入
oDataSet
这是输出
这是输出的示例,应该从上面输入中合并两个对象构建
//This is given array of object which can be many ,here I put just two instance in the array for demonstration purpose
var oDataSet = [{
__metadata: {
aaa: 111,
bbb: 222
},
to_ExcludedTerms: {results: []},
to_ListTypeGroupAssignment: {
results: [
{
AuthorisationGroup: 'AuthorisationGroup 1',
ListTypeGroup: 'ListTypeGroup1',
ListTypeGroupDescription: 'ListTypeGroupDescription 1',
ParentKey: '8ae25d47-c3cc-4ee3-a040-ea00505692111',
__metadata: {}
},
{
AuthorisationGroup: 'AuthorisationGroup 2',
ListTypeGroup: 'ListTypeGroup2',
ListTypeGroupDescription: 'ListTypeGroupDescription 2',
ParentKey: '34bcdc74-ab42-4538-8657-0a2b0473fcb7',
__metadata: {}
},
{
AuthorisationGroup: 'AuthorisationGroup 3',
ListTypeGroup: 'ListTypeGroup3',
ListTypeGroupDescription: 'ListTypeGroupDescription 3',
ParentKey: '34bcdc74-ab42-4538-8657-0a2b0473fcb5',
__metadata: {}
}
]
}
}, {
//This is the second instance of the object with same keys but different values
__metadata: {
aaa: 333,
bbb: 444
},
to_ExcludedTerms: {results: []},
to_ListTypeGroupAssignment: {
results: [
{
AuthorisationGroup: 'AuthorisationGroup 6',
ListTypeGroup: 'ListTypeGroup6',
ListTypeGroupDescription: 'ListTypeGroupDescription 6',
ParentKey: '8ae25d47-c3cc-4ee3-a040-ea00505692116',
__metadata: {}
},
{
AuthorisationGroup: 'AuthorisationGroup 7',
ListTypeGroup: 'ListTypeGroup7',
ListTypeGroupDescription: 'ListTypeGroupDescription 7',
ParentKey: '34bcdc74-ab42-4538-8657-0a2b0473fcb7',
__metadata: {}
},
{
AuthorisationGroup: 'AuthorisationGroup 8',
ListTypeGroup: 'ListTypeGroup8',
ListTypeGroupDescription: 'ListTypeGroupDescription 8',
ParentKey: '34bcdc74-ab42-4538-8657-0a2b0473fcb8',
__metadata: {}
}
]
}
}
];
//This is the values which I should search find in oDataSet
//The to_ListTypeGroupAssignment or other property which under the same structure
//should be with the following path but under the results which is the only
//hardcoded property
var aProperties = [
"to_ListTypeGroupAssignment/ListTypeGroup",
"to_ListTypeGroupAssignment/ListTypeGroupDescription"
]
只是为了澄清下面的评论:)
唯一可以硬编码的是var aSelectedDataSet = [
{
__metadata: {
aaa: 111,
bbb: 222
},
to_ListTypeGroupAssignment: {
results: [
{
ListTypeGroup: 'ListTypeGroup1',
ListTypeGroupDescription: 'ListTypeGroupDescription 1'
},
{
ListTypeGroup: 'ListTypeGroup2',
ListTypeGroupDescription: 'ListTypeGroupDescription 2',
},
{
ListTypeGroup: 'ListTypeGroup3',
ListTypeGroupDescription: 'ListTypeGroupDescription 3',
}
]
}
},
{
__metadata: {
aaa: 333,
bbb: 444
},
to_ListTypeGroupAssignment: {
results: [
{
ListTypeGroup: 'ListTypeGroup1',
ListTypeGroupDescription: 'ListTypeGroupDescription 1'
},
{
ListTypeGroup: 'ListTypeGroup2',
ListTypeGroupDescription: 'ListTypeGroupDescription 2',
},
{
ListTypeGroup: 'ListTypeGroup3',
ListTypeGroupDescription: 'ListTypeGroupDescription 3',
}
]
}
}
]
。
不任何属性名称,如ListTypeGroup& ListTypeGroupDescription
这应该是泛型并从aProperties
你看oData的结构应该如下
results
如果我需要更清楚,请告诉我如何,我应该添加哪些附加信息...这是在我尽可能更新问题之后......
答案 0 :(得分:4)
你可以使用这个递归的纯JavaScript函数:
下面的代码段将此函数应用于您提供的示例数据并返回所需的结果:
function extract(data, select, curpath) {
var result = {};
// Part of the path that has been traversed to get to data:
curpath = curpath || '';
if (typeof data !== 'object') { // data is a primitive (we assume)
return data;
}
if (typeof data.slice === 'function') { // data is an Array
return data.map(function (el, idx) {
return extract(el, select, curpath); // same path!
});
}
// data is an Object:
// The specific case of the "__metadata" property
if (data.__metadata !== undefined && curpath.length === 0) {
result.__metadata = data.__metadata;
}
// Core of this algorithm: take the relevant paths only...
var subselect = select.filter(function(path) {
return (path+'/').indexOf(curpath) == 0;
});
subselect.forEach(function (path, _, subselect) {
// then get the next property in such path...
var prop = path.substr(curpath.length).split('/')[0];
// and check if we have that property on the current object:
if (data[prop] !== undefined) {
// If so, recurse while adding this to the current path:
result[prop] = extract(data[prop], subselect, curpath+prop+'/');
}
});
// The specific case of the "results" property
if (data.results !== undefined) { // recurse with same path!
result.results = extract(data.results, select, curpath);
}
return result;
}
// Test data
var oDataSet = [{
__metadata: {
aaa: 111,
bbb: 222
},
to_ExcludedTerms: {results: []},
to_ListTypeGroupAssignment: {
results: [
{
AuthorisationGroup: 'AuthorisationGroup 1',
ListTypeGroup: 'ListTypeGroup1',
ListTypeGroupDescription: 'ListTypeGroupDescription 1',
ParentKey: '8ae25d47-c3cc-4ee3-a040-ea00505692111',
__metadata: {}
},
{
AuthorisationGroup: 'AuthorisationGroup 2',
ListTypeGroup: 'ListTypeGroup2',
ListTypeGroupDescription: 'ListTypeGroupDescription 2',
ParentKey: '34bcdc74-ab42-4538-8657-0a2b0473fcb7',
__metadata: {}
},
{
AuthorisationGroup: 'AuthorisationGroup 3',
ListTypeGroup: 'ListTypeGroup3',
ListTypeGroupDescription: 'ListTypeGroupDescription 3',
ParentKey: '34bcdc74-ab42-4538-8657-0a2b0473fcb5',
__metadata: {}
}
]
}
}, {
__metadata: {
aaa: 333,
bbb: 444
},
to_ExcludedTerms: {results: []},
to_ListTypeGroupAssignment: {
results: [
{
AuthorisationGroup: 'AuthorisationGroup 6',
ListTypeGroup: 'ListTypeGroup6',
ListTypeGroupDescription: 'ListTypeGroupDescription 6',
ParentKey: '8ae25d47-c3cc-4ee3-a040-ea00505692116',
__metadata: {}
},
{
AuthorisationGroup: 'AuthorisationGroup 7',
ListTypeGroup: 'ListTypeGroup7',
ListTypeGroupDescription: 'ListTypeGroupDescription 7',
ParentKey: '34bcdc74-ab42-4538-8657-0a2b0473fcb7',
__metadata: {}
},
{
AuthorisationGroup: 'AuthorisationGroup 8',
ListTypeGroup: 'ListTypeGroup8',
ListTypeGroupDescription: 'ListTypeGroupDescription 8',
ParentKey: '34bcdc74-ab42-4538-8657-0a2b0473fcb8',
__metadata: {}
}
]
}
}
];
var aProperties = [
"to_ListTypeGroupAssignment/ListTypeGroup",
"to_ListTypeGroupAssignment/ListTypeGroupDescription"
];
// (End of sample data)
// Call the function to get the result:
var aSelectedDataSet = extract(oDataSet, aProperties);
// For this snippet only: output the result in readable format
document.write('<pre>'+JSON.stringify(aSelectedDataSet, 0, 4)+'</pre>');
&#13;
代码被评论。这就是算法的工作原理:
__metadata
和results
显然有例外情况,在代码中会单独处理。
答案 1 :(得分:1)
您必须将oDataSet的每个属性与aSelectedDataSet
的每个属性进行比较var res=[];
for (var key1 in oDataSet){
for(var key2 in aSelectedDataSet ){
if(key1==key2){
res[key1]=oDataSet[key1];
}
}
}
修改强>
如果你定义像这样的过滤器
var filter={
__metadata:'',
to_ListTypeGroupAssignment:{
results:[{
ListTypeGroup:'',
ListTypeGroupDescription:''
}]
}
}
并将其应用于具有递归的数据
function recursiveValue(filter,data){
var res={};
for(var key in filter){
var val=data[key];
var p=filter[key];
if(val==='undefined') continue;
if(p===''){
res[key] = val;
}else if(Array.isArray(p)){
var tmp = [];
for(var i=0;i<val.length;i++){
tmp.push(recursiveValue(filter[key][0],val[i]));
}
res[key] = tmp;
}else if(typeof p=='object'){
res[key] = recursiveValue(filter[key],val);
}
}
return res;
}
喜欢这样
var results=[];
for(var i=0;i<oDataSet.length;i++){
results.push(recursiveValue(filter,oDataSet[i]));
}
你得到了
console.log(results);
答案 2 :(得分:1)
其中一个简短的解决方案是使用lodash。它具有[A-Z]+\s
功能,您将使用以下功能:
grep --color -Eo "\s-Dapp.inventory.id=[A-Z]+\s" inventory.txt
然而,它仅适用于第一级属性。
答案 3 :(得分:1)
您可以使用ES5提供的功能编程技术来解决这个问题。试试这个小提琴:https://jsfiddle.net/yh39of1b/3/
var aProperties = [
"to_ListTypeGroupAssignment/ListTypeGroup",
"to_ListTypeGroupAssignment/ListTypeGroupDescription"
];
//maps the properties you wish to capture
var propertyList = aProperties.map(function(properties) {
return properties.split('/');
});
//reduces the oData array to the data you require
aSelectedDataSet = oData.reduce(function(existing,current){
var obj = {};
//each iteration of oData goes through each property group
//first at the parent property level
propertyList.forEach(function(property){
if (typeof obj[property[0]] === 'undefined') {
obj[property[0]] = {};
obj[property[0]].results = [];
}
if(current[property[0]]) {
//now at the child property level
current[property[0]].results.forEach(function(result,index){
if(typeof obj[property[0]].results[index] === 'undefined')
obj[property[0]].results[index] = {};
obj[property[0]].results[index][property[1]] = result[property[1]];
});
}
});
//add the newly mapped object to the aSelectedDataSet array
existing.push(obj);
return existing;
},[]);
答案 4 :(得分:1)
不是最优雅的方式,但有效。
比较嵌套结构并删除不需要的键。
限制:
1. __metadata
是硬编码的
2. results
是硬编码的
您想要的输出与生成的输出不同,不同之处在于 你的输出:
aSelectedDataSet[2].to_ListTypeGroupAssignment.results[1].ListTypeGroupDescription === 1
而在生成的输出中,它是:
aSelectedDataSet[2].to_ListTypeGroupAssignment.results[1].ListTypeGroupDescription === 6
我认为,这是你问题上的一个错字。
代码:
var convertPropertyRelation = function(propertiesArray) {
if (!Array.isArray(propertiesArray))
return [];
var formattedProperties = {},
i, len = propertiesArray.length,
currentRelation;
for (i = 0; i < len; i++) {
currentRelation = propertiesArray[i].split('/');
if (formattedProperties.hasOwnProperty(currentRelation[0])) {
formattedProperties[currentRelation[0]].push(currentRelation[1]);
} else {
formattedProperties[currentRelation[0]] = [currentRelation[1]];
}
}
return formattedProperties;
};
var generateDataSet = function() {
var formattedProperties = convertPropertyRelation(aProperties),
firstRelation = Object.keys(formattedProperties),
i, len = firstRelation.length,
j, resultArray, resultLength;
var dataSet = oDataSet.map(function(dataSetObject) {
for (var firstKey in dataSetObject) {
if (firstKey === '__metadata') {
continue;
} else if (firstRelation.indexOf(firstKey) === -1) {
delete dataSetObject[firstKey];
} else {
// if first relation is present
if (dataSetObject.hasOwnProperty(firstKey)) {
// results array in the firstRelation
resultArray = dataSetObject[firstKey].results;
// for all results
for (j = 0, resultLength = resultArray.length; j < resultLength; j++) {
// for all keys in current result
for (var respectiveKey in resultArray[j]) {
// if the key is present leave it as it is
if (formattedProperties[firstKey].indexOf(respectiveKey) === -1) {
delete resultArray[j][respectiveKey];
}
}
}
}
}
}
return dataSetObject;
});
return dataSet;
};