![](/img/trans.png)
[英]Filter array by object property, then add together another property's values between the filtered objects
[英]JS: How to filter an array of objects, add to the first object a key with values of the rest of filtered elements?
我正在嘗試在 Tabulator JS 中實現用戶從表中重建具有樹結構的新表的機會。 所以 tableData 是一個假定的表,而 columnTree 是用戶的選擇,哪一列必須是樹根。
我的想法是首先將唯一的鍵值存儲在一個數組中,然后遍歷 tableData 按每個鍵對其進行過濾,將過濾對象的 rest 的值添加到第一個元素 [_children] 鍵。
var columnTree = "continent";
var tableData = [
{continent:"Asia", country:"China"},
{continent:"Asia", country:"Vietnam"},
{continent:"Asia", country:"Thai"},
{continent:"America", country:"USA"},
{continent:"America", country:"Canada"},
{continent:"Africa", country:"Egypt"},
{continent:"Africa", country:"Somalia"},
];
獲取唯一鍵
var unique = tableDataNested.map(item => item[columnTree]).filter((value, index, self) => self.indexOf(value) === index);
// ["Asia", "America", "Afrika"]
過濾器 function
function filterByValue(array, string) {
return array.filter(o =>
Object.keys(o).some(k => o[k].toLowerCase().includes(string.toLowerCase())));
};
最后一步
var finalArray = [];
unique.forEach(function(continent) {
//temporary array with values of each continent
var tempArray = filterByValue(tableDataNested, continent);
console.log(tempArray);
//get the first object
console.log(tempArray[0]);
//add to the first object '_children' key with values of the rest of objects except the
//first.
var finalResult = tempArray[0]['_children'] = [tempArray.slice(1)];
console.log(finalResult);
finalArray.push(finalResult);
});
問題是,它在第二大陸墜毀,我不明白為什么
VM480:3 Uncaught TypeError: o[k].toLowerCase is not a function
at <anonymous>:3:51
at Array.some (<anonymous>)
at <anonymous>:3:36
at Array.filter (<anonymous>)
at filterByValue (<anonymous>:2:30)
at <anonymous>:2:33
at Array.forEach (<anonymous>)
at <anonymous>:1:8
我的理想結果是
var finalArray = [
{continent:"Asia", country:"China", "_children": [
{continent:"Asia", country:"Vietnam"},
{continent:"Asia", country:"Thai"}
]},
{continent:"America", country:"USA", "_children": [
{continent:"America", country:"Canada"},
]},
{continent:"Africa", country:"Egypt", "_children": [
{continent:"Africa", country:"Somalia"}
]}
];
例如,您最好使用通用groupBy
function groupBy(ary, fn) {
let m = new Map();
for (let x of ary) {
let key = fn(x);
if (!m.has(key))
m.set(key, []);
m.get(key).push(x);
}
return m;
}
接着
let groupMap = groupBy(tableData, x => x[columnTree]);
let result = [];
for (let [first, ...rest] of groupMap.values()) {
first._children = rest;
result.push(first);
}
請注意,這也會改變原始tableData
數組,如果不希望這樣做,請將循環體更改為:
result.push({...first, _children: rest});
.reduce
來聚合您的數據。
reduce()
方法對數組的每個元素執行一個化簡器 function(您提供),從而產生一個 output 值。
var tableData = [ {continent:"Asia", country:"China"}, {continent:"Asia", country:"Vietnam"}, {continent:"Asia", country:"Thai"}, {continent:"America", country:"USA"}, {continent:"America", country:"Canada"}, {continent:"Africa", country:"Egypt"}, {continent:"Africa", country:"Somalia"}, ]; var result = tableData.reduce((acc, item) => { if(acc[item.continent] === undefined) acc[item.continent] = { continent: item.continent, country: item.country, _children: []} else acc[item.continent]._children.push(item); return acc; }, {}); console.log(Object.values(result));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.