2017-09-19 91 views
0

所以我有这样的阵列从JSON获取阵列字段名称

data : [{ 
    article_categories : { 
     id : "xxx", 
     name : "xxx" 
    }, 
    article : "xxx", 
    publisher : "xxx" 
}] 

我想为那些阵列另一个多维数组,我想保留的字段名(名字"article""publisher"等在那里的阵列)与价值,但我不知道让字段名称

,我也希望做一些有条件的,如果只包括某些领域成为我的新阵列通过从该阵列检查

thead: [ 
    { key: "article"}, 
    { key: "article_categories.name"}, 
    ..... 
] 

,所以我最终会有这样

newArray: [ 
{article:"xxx",publisher: "xxx",article_categories.name:"xxx"}, 
{article:"xxx",publisher: "xxx",article_categories.name:"xxx"} 
.... 
] 

阵列如何做到这一点?我试图

thead.forEach(function(column){ 
    data.forEach(function(key,value){ 
     if(column.key == key){ 
     newArray[key] = value 
     } 
    }) 
}) 

,但它只是不工作....

回答

1

如果你打开使用lodash,这将是如此简单。 Lodash在使用.get()方法评估JSON表达式方面非常高效,因此您不会为评估对象的表达式而烦恼。

.chain()增加了锦上添花的效果,使代码更易于阅读,但在底层执行许多复杂的操作。

尝试下面的代码片段:

var keys = [{ 
 
    key: "article" 
 
    }, 
 
    { 
 
    key: "article_categories.name" 
 
    } 
 
]; 
 

 
var data = [{ 
 
    article_categories: { 
 
    id: "xxx", 
 
    name: "xxx" 
 
    }, 
 
    article: "xxx", 
 
    publisher: "xxx" 
 
}]; 
 

 
var result = _.chain(data) 
 
    .map(function(item) { 
 
    var object = {}; 
 

 
    keys.forEach(function(key) { 
 
     object[key.key] = _.get(item, key.key); 
 
    }); 
 

 
    return object; 
 
    }) 
 
    .value(); 
 

 
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

+4

,需要加载一个70KB的keys(精缩!)库只是遍历数组。 ..:/ –

+0

以及我已经使用lodash所以我不介意,但对不起,我有另一个问题,但仍然与此有关...如果我的thead json数组是一个对象,并且像这样:this:{article:“string”,publisher:“string”,....}如何修改这些代码? –

+0

@LaurensiusTony - 在这种情况下,您只会对对象的关键点感兴趣。所以,你可以用'_.keys(tdata).forEach(...)'替换'keys.forEach'。 – 31piy

1

我认为,首先,你应该简化这个:

thead = [ 
    { key: "article"}, 
    { key: "article_categories.name"}, 
    ..... 
] 

就象这样:

thead = ["article", "article_categories.name"] 

这是我走在它:

const data = [{ 
 
\t \t article_categories : { 
 
\t \t \t id : "xxx", 
 
\t \t \t name : "xxx" 
 
\t \t }, 
 
\t \t article : "xxx", 
 
\t \t publisher : "xxx" 
 
\t }], 
 
\t thead = ["article", "article_categories.name"] 
 

 
const newArray = data.map(obj => { 
 
\t let output = {} 
 
\t thead.forEach(key => { 
 
\t \t if(key.includes(".")){ 
 
\t \t \t let subkeys = key.split(".") 
 
\t \t \t output[key] = obj[subkeys[0]][subkeys[1]] 
 
\t \t } else { 
 
\t \t \t output[key] = obj[key] 
 
\t \t } 
 
\t }) 
 
\t return output 
 
}) 
 

 
console.log(newArray)

+0

如果'article_categories.name'改为像'a.b [0] .c'这样的东西怎么办?使用lodash在加载库方面很痛苦,但在这种情况下更适合,因为解析JSON表达式并对其进行评估就像重新发明轮子一样,并且当然容易出错。 – 31piy

+0

如果改变了,那么代码将需要调整。在此期间,OP没有说改变它,这回答了这个问题,并没有加载一个70K的库;) –

+0

哈哈,这证明了现在:) – 31piy

1

可以使用flatten功能扁平化与点符号的对象。

然后map扁平对象采取一种itemfilterkey s表示被允许和reduce到重建对象。

要回答你原来的问题,你可以使用Object.keys()获取对象

let data = [{ 
 
    article_categories : { 
 
     id : "xxx", 
 
     name : "xxx" 
 
    }, 
 
    article : "xxx", 
 
    publisher : "xxx" 
 
},{ 
 
    article_categories : { 
 
     id : "xxx2", 
 
     name : "xxx2" 
 
    }, 
 
    article : "xxx2", 
 
    publisher : "xxx2" 
 
}] 
 

 
let thead = [ 
 
    { key: "article"}, 
 
    { key: "article_categories.name"}, 
 
]; 
 

 
let allowed_keys = thead.map(x=> x.key); 
 

 
let flattened = data.map(item => flatten(item, '', '')); 
 

 
// console.log(flattened); 
 

 
let result = flattened.map(item => { 
 
    return Object.keys(item) 
 
    .filter(key => allowed_keys.includes(key)) 
 
    .reduce((obj, key) => { 
 
     obj[key] = item[key]; 
 
     return obj; 
 
    }, {}) 
 
}); 
 

 
console.log(result); 
 

 

 
/** 
 
* Recursively flattens a JSON object using dot notation. 
 
* 
 
* NOTE: input must be an object as described by JSON spec. Arbitrary 
 
* JS objects (e.g. {a:() => 42}) may result in unexpected output. 
 
* MOREOVER, it removes keys with empty objects/arrays as value (see 
 
* examples bellow). 
 
* 
 
* @example 
 
* // returns {a:1, 'b.0.c': 2, 'b.0.d.e': 3, 'b.1': 4} 
 
* flatten({a: 1, b: [{c: 2, d: {e: 3}}, 4]}) 
 
* // returns {a:1, 'b.0.c': 2, 'b.0.d.e.0': true, 'b.0.d.e.1': false, 'b.0.d.e.2.f': 1} 
 
* flatten({a: 1, b: [{c: 2, d: {e: [true, false, {f: 1}]}}]}) 
 
* // return {a: 1} 
 
* flatten({a: 1, b: [], c: {}}) 
 
* 
 
* @param obj item to be flattened 
 
* @param {Array.string} [prefix=[]] chain of prefix joined with a dot and prepended to key 
 
* @param {Object} [current={}] result of flatten during the recursion 
 
* 
 
* @see https://docs.mongodb.com/manual/core/document/#dot-notation 
 
*/ 
 
function flatten (obj, prefix, current) { 
 
    prefix = prefix || [] 
 
    current = current || {} 
 
    if (typeof (obj) === 'object' && obj !== null) { 
 
    Object.keys(obj).forEach(key => { 
 
     flatten(obj[key], prefix.concat(key), current) 
 
    }) 
 
    } else { 
 
    current[prefix.join('.')] = obj 
 
    } 
 
    return current 
 
}