2017-09-19 88 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 
 
}