Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
181 views
in Technique[技术] by (71.8m points)

javascript - 分组和排序数组(Group and sort array)

I have data that is coming from the server like this(我有这样的数据来自服务器)

let value = [ { 'commongId': 1, 'principal': true, 'creationDate': '2019-11-03:40:00' }, { 'commongId': 2, 'principal': false, 'creationDate': '2017-10-25T01:35:00' }, { 'commongId': 2, 'principal': true, 'creationDate': '2019-05-25T08:00:00' }, { 'commongId': 1, 'principal': false, 'creationDate': '2018-11-25T09:40:00' }, { 'commongId': 1, 'principal': false, 'creationDate': '2017-11-25T09:40:00' }, { 'commongId': 2, 'principal': false, 'creationDate': '2018-05-25T08:00:00' }, ] I want to transform it in a way that the courses are grouped by commonId , and that the principal course of each 'id' should appear first, and the rest of the courses belonging to the same commonId come after that principal course sorted by the creation date (asc).(我想对它进行某种转换,使课程按commonId分组,并且每个“ id”的主要课程应首先出现,而属于同一commonId的其余课程则在该主要课程之后(按创建顺序排序)日期(升序)。) So basically the output should be(所以基本上输出应该是) let value = [ { commongId: 1, principal: true, creationDate: '2019-11-03:40:00' }, { commongId: 1, principal: false, creationDate: '2017-11-25T09:40:00' }, { commongId: 1, principal: false, creationDate: '2018-11-25T09:40:00' }, { commongId: 2, principal: true, creationDate: '2019-05-25T08:00:00' }, { commongId: 2, principal: false, creationDate: '2017-10-25T01:35:00' }, { commongId: 2, principal: false, creationDate: '2018-05-25T08:00:00' } ]; I have a working solution, which in my opinion looks horrible and too complicated.(我有一个可行的解决方案,我认为这看起来太可怕了,太复杂了。) // function to group the the courses by commonId const groupBy = (data, keyFn) => data.reduce((agg, item) => { const group = keyFn(item); agg[group] = [...(agg[group] || []), item]; return agg; }, {}); let transformedValue = groupBy(courses, item => item.commonId); //removing the keys from the array of objects transformedValue = Object.keys(transformedValue).map(k => transformedValue[k]); // sorting each inner array by creationDate transformedValue = transformedValue.map(el => { let modified = el.sort((a, b) => moment(a.creationDate).diff(moment(b.creationDate)) ); // pushing the principal object of each array to the top const foundIndex = modified.findIndex(element => element.principal); if (foundIndex > -1) { const foundElement = modified.find(element => element.principal); modified.splice(foundIndex, 1); modified.unshift(foundElement); } return modified; }); // flattening the array to one level transformedValue = transformedValue.flat(); // using the transformed value in the subscription of(transformedValue).subscribe(p => { this.dataToShow = p; });   ask by AngularDebutant translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You could use sort like this.(您可以使用像这样的sort 。)

const value=[{commongId:1,principal:true,creationDate:"2019-11-03:40:00"},{commongId:2,principal:false,creationDate:"2017-10-25T01:35:00"},{commongId:2,principal:true,creationDate:"2019-05-25T08:00:00"},{commongId:1,principal:false,creationDate:"2018-11-25T09:40:00"},{commongId:1,principal:false,creationDate:"2017-11-25T09:40:00"},{commongId:2,principal:false,creationDate:"2018-05-25T08:00:00"},]; value.sort((a, b) => a.commongId - b.commongId || b.principal - a.principal || a.creationDate.localeCompare(b.creationDate) ) console.log(value) The array will first be sorted based on commongId .(首先将基于commongId对数组进行排序。) If both have the same commongId , the subtraction will return 0. So, ||(如果两者具有相同commongId ,减法将返回0。所以, ||) will check the next expression because 0 is falsy value.(将检查下一个表达式,因为0falsy值。) Then, it will be sorted based on principal .(然后,将基于principal对其进行排序。) You can subtract 2 boolean values because it returns 1, -1 or 0 based on the value.(您可以减去2个布尔值,因为它会基于该值返回1,-1或0。) true - false === 1 false - true === -1 true - true === 0 If they still have the same value for commongId and principal , the array will be sorted based on the creationDate .(如果它们的commongIdprincipal值仍然相同, commongId基于creationDate对数组进行排序。) Since the dates are in the ISO format, you can do a string comparison using localeCompare .(由于日期采用ISO格式,因此可以使用localeCompare进行字符串比较。) If the date is in some other format, you could do(如果日期采用其他格式,则可以) new Date(a.creationDate) - new Date(b.creationDate)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...