簡體   English   中英

JavaScript:如何對嵌套數組進行分組

[英]JavaScript: How to group nested array

我試圖使用React Native中的SectionList顯示數據。 我已經編寫了下面的代碼,顯示了我想要完成的任務。

我希望數據首先按date組合在一起,在那個日期之內,我需要按位置分組。 常規JavaScript解決方案將起作用。 它具有titledata密鑰非常重要。

我的輸入數據采用以下格式:

[ { game_id: 1171,
    date: '2018-11-17',
    location: 'Plaza'
   },
  { game_id: 1189,
    date: '2018-11-17',
    location: 'Field - Kickball'
   },
   { game_id: 1489,
    date: '2018-11-16',
    location: 'Field - Kickball'
   },
   { game_id: 1488,
    date: '2018-11-16',
    location: 'Field - Soccer'
   }
]

我需要從上面的數據數組中獲取以下輸出:

data = [{
    title: "2018-11-17",
    data: [{
            title: "Field - Kickball",
            data: [{
                game_id: 1189,
                date: '2018-11-17',
                location: 'Field - Kickball'
            }]
        },
        {
            title: "Plaza",
            data: [{
                game_id: 1171,
                date: '2018-11-17',
                location: 'Plaza'
            }]
        }
    ]
    },
    {
        title: "2018-11-16",
        data: [{
                title: "Field - Kickball",
                data: [{
                    game_id: 1489,
                    date: '2018-11-16',
                    location: 'Field - Kickball'
                }]
            },
            {
                title: "Field - Soccer",
                data: [{
                    game_id: 1488,
                    date: '2018-11-16',
                    location: 'Field - Soccer'
                }]
            }
        ]
    }
]

我已經嘗試過了:

const games = [data here]
var groups = _(games)
.groupBy(x => x.date)
        .map(value => {
            return _.groupBy(value, 'location')
            .map(({key, value}) => ({title: key, data: value}))
        })

        .map((value, key) => {
            return ({title: value[Object.keys(value)[0]][0].date, data: value})
        })

有幾種方法可以實現,但是一個不需要第三方依賴的簡單方法,如Underscore或Lodash,可以使用內置的Array#reduce()方法實現,如下所示。

有關此解決方案如何工作的詳細信息,請參閱以下代碼段中的文檔:

 const input = [ { game_id: 1171, date: '2018-11-17', location: 'Plaza' }, { game_id: 1189, date: '2018-11-17', location: 'Field - Kickball' }, { game_id: 1489, date: '2018-11-16', location: 'Field - Kickball' }, { game_id: 1488, date: '2018-11-16', location: 'Field - Soccer' } ]; /* Reduce input data to required nested sub-array structure */ const data = input.reduce((result, item) => { /* Construct item to be inserted into sub array for this item.date in resulting data object */ const resultItem = { title: item.location, data: [{ game_id: item.game_id, date: item.date, location: item.location }] }; /* Find existing item in result array with title that matches date */ const resultDateList = result.find(i => i.title === item.date); if (resultDateList) { /* If matching sublist found, add constructed item to it's data array */ resultDateList.data.push(resultItem); } else { /* If not matching sublist found, add a new one to the result for this item and pre-populate the data array with new item*/ result.push({ title: item.date, data: [resultItem] }); } return result; }, []) console.log(data) 

希望有所幫助!

你可以用ES6和沒有lodash做這樣的事情:

 let arr = [ { game_id: 1171, date: '2018-11-17', location: 'Plaza' }, { game_id: 1189, date: '2018-11-17', location: 'Field - Kickball' }, { game_id: 1489, date: '2018-11-16', location: 'Field - Kickball' }, { game_id: 1488, date: '2018-11-16', location: 'Field - Soccer' } ] let groupByfield = (data, field) => data.reduce((r, c) => { let key = c[field] r[key] = r[key] || {title: key, data: []} r[key].data = [...(r[key].data || []), c] return r }, {}) let result = Object.values(groupByfield(arr, 'date')) .map(x => ({ title: x.title, data: Object.values(groupByfield(x.data, 'location')) }) ) console.log(result) 

我們的想法是創建自定義groupBy函數,然后將其用於您的分組。

我們正在使用Array.reduceArray.mapObject.values

如果你想要一個標准的解決方案,那么你可以先減少一個對象,然后返回該對象的值,然后再在輸出上分組:)

 function groupBy( arr, prop ) { return Object.values( arr.reduce( ( aggregate, item ) => { const val = item[prop]; if (!aggregate[val]) { aggregate[val] = { [prop]: val, data: [] }; } aggregate[val].data.push( item ); return aggregate; }, {} ) ); } const games = [ { game_id: 1171, date: '2018-11-17', location: 'Plaza' }, { game_id: 1189, date: '2018-11-17', location: 'Field - Kickball' }, { game_id: 1489, date: '2018-11-16', location: 'Field - Kickball' }, { game_id: 1488, date: '2018-11-16', location: 'Field - Soccer' } ]; const grouped = groupBy( games, 'date' ) .map( item => ({ ...item, data: groupBy( item.data, 'location' ) }) ); console.log( grouped ); 

請注意,我只使用提取的prop作為分組的目標屬性,如果你想要title ,只需將[prop]: val更改為'title': val然后你就可以讓你的第二個分組變得更容易了:)

使用_.flow()生成一個函數,該函數可以按字段對數組進行分組,並將其轉換為{title,data}格式。 該函數還應接受數據轉換器。 現在,您可以遞歸地使用它來多次分組。

 const { identity, flow, partialRight: pr, groupBy, map } = _ const groupByKey = (key, transformer = identity) => flow( pr(groupBy, key), pr(map, (data, title) => ({ title, data: transformer(data) })) ) const data = [{"game_id":1171,"date":"2018-11-17","location":"Plaza"},{"game_id":1189,"date":"2018-11-17","location":"Field - Kickball"},{"game_id":1489,"date":"2018-11-16","location":"Field - Kickball"},{"game_id":1488,"date":"2018-11-16","location":"Field - Soccer"}] const result = groupByKey('date', groupByKey('location'))(data) console.log(result) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script> 

和lodash / fp一樣的想法:

 const { identity, flow, groupBy, map, get } = _ const groupByKey = (key, transformer = identity) => flow( groupBy(key), map(data => ({ title: get([0, key], data), data: transformer(data) })) ) const data = [{"game_id":1171,"date":"2018-11-17","location":"Plaza"},{"game_id":1189,"date":"2018-11-17","location":"Field - Kickball"},{"game_id":1489,"date":"2018-11-16","location":"Field - Kickball"},{"game_id":1488,"date":"2018-11-16","location":"Field - Soccer"}] const result = groupByKey('date', groupByKey('location'))(data) console.log(result) 
 <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM