簡體   English   中英

如何按 JavaScript 中不同鍵的值對對象數組進行排序?

[英]How to sort array of objects by value of different keys in JavaScript?

我有一個包含 user_id、score、time_taken 等的數組。

我想設置類似數組的每個用戶分數將被添加到唯一用戶的唯一數組中,並將按他的分數和 time_taken 值排序。

這是我的代碼

let data = [
    { "user_id": "8-a-1", "course_id": 802, "score": 10, "time_taken": 284000 },
    { "user_id": "8-a-1", "course_id": 802, "score": 10, "time_taken": 284000 },
    { "user_id": "8-a-1", "course_id": 802, "score": 10, "time_taken": 284000 },
    { "user_id": "8-a-1", "course_id": 803, "score": 10, "time_taken": 284000 },
    { "user_id": "5-a-1", "course_id": 502, "score": 10, "time_taken": 284000 },
    { "user_id": "5-a-2", "course_id": 502, "score": 10, "time_taken": 284000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 10, "time_taken": 296000 },
    { "user_id": "5-a-1", "course_id": 502, "score": 0, "time_taken": 293000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 502, "score": 30, "time_taken": 287000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 504, "score": 20, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 504, "score": 10, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
    { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 },
]

我試圖減少數組

data = data.reduce((c, i) => {
    c[i.user_id] = (c[i.user_id] || 0) + parseFloat(i.score)
    return c
}, {});

我想要這樣的結果

[
{user_id: "5-a-1", score: 80, time_taken: "total time taken will be count"},
{user_id: "5-a-2", score: 30, time_taken: "total time taken will be count"},
{user_id: "8-a-1", score: 10, time_taken: "total time taken will be count"},
]

 let data = [ { "user_id": "8-a-1", "course_id": 802, "score": 10, "time_taken": 284000 }, { "user_id": "8-a-1", "course_id": 802, "score": 10, "time_taken": 284000 }, { "user_id": "8-a-1", "course_id": 802, "score": 10, "time_taken": 284000 }, { "user_id": "8-a-1", "course_id": 803, "score": 10, "time_taken": 284000 }, { "user_id": "5-a-1", "course_id": 502, "score": 10, "time_taken": 284000 }, { "user_id": "5-a-2", "course_id": 502, "score": 10, "time_taken": 284000 }, { "user_id": "5-a-1", "course_id": 503, "score": 10, "time_taken": 296000 }, { "user_id": "5-a-1", "course_id": 502, "score": 0, "time_taken": 293000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 502, "score": 30, "time_taken": 287000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 504, "score": 20, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 504, "score": 10, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, ] const result = data.reduce((prev, elem)=>{ if(prev[elem.user_id]){ prev[elem.user_id] = { ...prev[elem.user_id], score: prev[elem.user_id].score + elem.score, time_taken: prev[elem.user_id].time_taken + elem.time_taken } }else{ prev[elem.user_id] = elem } return prev; },{}) let ar = [] for(let key in result){ ar.push(result[key]) } const finalResult = ar.sort((a,b)=>b.score-a.score) console.log(finalResult)

這不僅僅是排序,而且可能是一個reducemapsort的序列:

 let data = [ { "user_id": "8-a-1", "course_id": 802, "score": 10, "time_taken": 284000 }, { "user_id": "8-a-1", "course_id": 802, "score": 10, "time_taken": 284000 }, { "user_id": "8-a-1", "course_id": 802, "score": 10, "time_taken": 284000 }, { "user_id": "8-a-1", "course_id": 803, "score": 10, "time_taken": 284000 }, { "user_id": "5-a-1", "course_id": 502, "score": 10, "time_taken": 284000 }, { "user_id": "5-a-2", "course_id": 502, "score": 10, "time_taken": 284000 }, { "user_id": "5-a-1", "course_id": 503, "score": 10, "time_taken": 296000 }, { "user_id": "5-a-1", "course_id": 502, "score": 0, "time_taken": 293000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 502, "score": 30, "time_taken": 287000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 504, "score": 20, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 504, "score": 10, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, { "user_id": "5-a-1", "course_id": 503, "score": 0, "time_taken": 299000 }, ]; let red=data.reduce((acc,cur)=>{ let usr=acc[cur.user_id] || (acc[cur.user_id]={score:0,time:0}); usr.score+=cur.score; usr.time+=cur.time_taken; return acc; },{}); console.log("Reduced to an object with 3 keys"); console.log(red); let result=Object.keys(red).map(key=>{ let usr=red[key]; return { user_id:key, score:usr.score, time:usr.time } }); console.log("Mapped to an array"); console.log(result); result.sort((a,b)=>a.user_id.localeCompare(b.user_id)); console.log("Sorted by user_id"); console.log(result);

我會使用lodash因為它可以輕松分組並生成更具可讀性的代碼。 使用您的data數組:

import _ from 'lodash';

const data = [...]; // As given in the question

// This will form a new row as the initial accumulator for reducing a group
function newRow(key) {
  return { user_id: key, score: 0, time_taken: 0 };
}

// reduce iterator that adds the values of a row to the accumulated values
function addRow(result, row, key) {
  return {
    ...result,
    score: result.score + row.score,
    time_taken: result.time_taken + row.time_taken,
  };
} 

// reduce a group of rows
function reduceRows(group, key) {
  return _.reduce(group, addRow, newRow(key));
}

// group the data by user_id
let res = _.groupBy(data, "user_id");

// convert into array, one entry per group
// each group gets reduced to a single row
res = _.map(res, reduceRows);

// since groupBy initially returns object that may not be sorted, sort it now
res = _.sortBy(res, "user_id");

REPL

或者,如果您使用 FP,使用 lodash 的 FP 版本允許您進行組合:

import _ from 'lodash/fp';

// Make map expose key, see: https://github.com/lodash/lodash/issues/1781
const map = _.map.convert({ 'cap': false });

const data = [...]; // As given in the question

const newRow = key => ({ user_id: key, score: 0, time_taken: 0 });

const addRow = (result, row, key) => ({
  ...result,
  score: result.score + row.score,
  time_taken: result.time_taken + row.time_taken,
}); 

const reduceRows = (group, key) => _.reduce(addRow, newRow(key), group);

const res = _.compose(
  _.sortBy("user_id"),
  map(reduceRows),
  _.groupBy("user_id"),
)(data);

REPL

暫無
暫無

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

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