简体   繁体   English

React - 按降序对对象进行排序,在更改时重新渲染 DOM

[英]React - sort object by descending order, rerender DOM on a change

I have a react app I'm working on, where I need to update the DOM again after a change has been made - sorting numbers from highest to lowest based on word count in a paragraph.我有一个正在开发的 React 应用程序,在进行更改后我需要再次更新 DOM - 根据段落中的字数从高到低对数字进行排序。

So far this looks like this:到目前为止,这看起来像这样:

import "./styles.css";
// this represents a couple of paragraphs where we count the words
import text from "./text.js";

export default function App() {
  let allTheWords = text.split(" ");
  let countData = [];
  let theWordCount = {};
  const createTable = () => {
    for (const num of allTheWords) {
      theWordCount[num] = theWordCount[num] ? theWordCount[num] + 1 : 1;
    }
    for (const property in theWordCount) {
      countData.push(
        <tr key={property}>
          <td>{property}</td>
          <td>{theWordCount[property]}</td>
        </tr>
      );
    }
  };
  createTable();
  // let's sort the words, but we need to go from high to small
  const sortWords = () => {
    theWordCount = Object.entries(theWordCount)
      .sort(([, a], [, b]) => a - b)
      .reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
    console.log("OKAY I THINK WE SORTED: " + JSON.stringify(theWordCount));
    createTable();
  };
  return (
    <div>
      <button onClick={sortWords}>SORT WORDS</button>
      <table>
        <tbody>
          <tr>
            <th>Word</th>
            <th>Count</th>
          </tr>
          {countData}
        </tbody>
      </table>
    </div>
  );
}

The output of this block is this:这个块的输出是这样的:

OKAY I THINK WE SORTED: {"10":1,"27":1,"1815":1,"1842":1,"1852":1,"Augusta":1,"King,":1,"(née":1,"Byron;":1,"December":1,"–":1,"November":1,"1852)":1,"English":1,"writer,":1,"chiefly":1,"proposed":1,"mechanical":1,"general-purpose":1,"computer,":1,"recognise":1,"machine":1,"had":1,"applications":1,"pure":1,"calculation,":1,"have":1,"published":1,"intended":1,"As":1,"result,":1,"regarded":1,"programmer.[2][3][4]\n\nAda":1,"child":1,"poet":1,"Lord":1,"Lady":1,"Byron.[5]":1,"All":1,"Byron's":1,"children":1,"were":1,"wedlock":1,"women.[6]":1,"separated":1,"his":1,"wife":1,"month":1,"after":1,"left":1,"England":1,"forever":1,"four":1,"months":1,"later.":1,"commemorated":1,"parting":1,"poem":1,"begins,":1,"\"Is":1,"face":1,"like":1,"mother's":1,"fair":1,"child!":1,"ADA!":1,"sole":1,"daughter":1,"house":1,"heart?\".[7]":1,"Greece":1,"when":1,"eight":1,"old.":1,"mother":1,"bitter":1,"promoted":1,"Ada's":1,"interest":1,"mathematics":1,"logic":1,"effort":1,"prevent":1,"developing":1,"father's":1,"perceived":1,"insanity.":1,"Despite":1,"this,":1,"him,":1,"naming":1,"two":1,"sons":1,"Gordon.":1,"Upon":1,"death,":1,"buried":1,"next":1,"request.":1,"Although":1,"ill":1,"childhood,":1,"pursued":1,"studies":1,"assiduously.":1,"married":1,"William":1,"1835.":1,"made":1,"Earl":1,"1838,":1,"thereby":1,"becoming":1,"Lovelace.\n\nHer":1,"educational":1,"social":1,"exploits":1,"brought":1,"into":1,"contact":1,"scientists":1,"Andrew":1,"Crosse,":1,"Sir":1,"David":1,"Brewster,":1,"Wheatstone,":1,"Michael":1,"Faraday":1,"author":1,"Dickens,":1,"contacts":1,"which":1,"used":1,"further":1,"education.":1,"described":1,"approach":1,"science\"[8]":1,"herself":1,"\"Analyst":1,"(&":1,"Metaphysician)\".[9]\n\nWhen":1,"teenager":1,"(18),":1,"mathematical":1,"talents":1,"long":1,"working":1,"relationship":1,"friendship":1,"fellow":1,"British":1,"who":1,"\"the":1,"father":1,"computers\".":1,"particular":1,"met":1,"June":1,"1833,":1,"through":1,"their":1,"mutual":1,"friend,":1,"private":1,"tutor,":1,"Mary":1,"Somerville.\n\nBetween":1,"1843,":1,"translated":1,"article":1,"Italian":1,"military":1,"engineer":1,"Luigi":1,"Menabrea":1,"engine,":1,"supplementing":1,"it":1,"elaborate":1,"set":1,"notes,":1,"simply":1,"called":1,"\"Notes\".":1,"Lovelace's":1,"are":1,"important":1,"early":1,"history":1,"computers,":1,"containing":1,"what":1,"consider":1,"program—that":1,"is,":1,"designed":1,"Other":1,"historians":1,"reject":1,"this":1,"perspective":1,"point":1,"personal":1,"1836/1837":1,"contain":1,"programs":1,"engine.[10]":1,"also":1,"developed":1,"vision":1,"capability":1,"computers":1,"go":1,"mere":1,"or":1,"number-crunching,":1,"while":1,"others,":1,"including":1,"Babbage":1,"himself,":1,"focused":1,"those":1,"capabilities.[11]":1,"mindset":1,"science\"":1,"ask":1,"questions":1,"Engine":1,"(as":1,"shown":1,"notes)":1,"examining":1,"how":1,"individuals":1,"society":1,"relate":1,"technology":1,"collaborative":1,"tool.[6]\n\nShe":1,"uterine":1,"cancer":1,"age":1,"36.":1,"Countess":2,"known":2,"for":2,"work":2,"Engine.":2,"beyond":2,"algorithm":2,"carried":2,"such":2,"machine.":2,"is":2,"often":2,"computer":2,"only":2,"other":2,"born":2,"He":2,"thy":2,"my":2,"died":2,"years":2,"Her":2,"remained":2,"interested":2,"him":2,"at":2,"King":2,"Babbage,":2,"\"poetical":2,"led":2,"about":2,"calculating":2,"notes":2,"many":2,"Lovelace":3,"mathematician":3,"on":3,"Babbage's":3,"Analytical":3,"that":3,"be":3,"by":3,"from":3,"with":3,"She":4,"out":4,"she":4,"Byron":4,"Charles":5,"an":6,"first":6,"as":6,"Ada":8,"was":9,"a":9,"to":13,"in":14,"of":15,"and":16,"her":16,"the":18}

So now what we need to do, is sort this from highest number to lowest number.所以现在我们需要做的是从最高数字到最低数字排序。

Sorting object property by values 按值排序对象属性

In ES8, you can use Object.entries() to convert the object into an array:在 ES8 中,您可以使用 Object.entries() 将对象转换为数组:

const maxSpeed = { car: 300, bike: 60, motorbike: 200, airplane: 1000, helicopter: 400, rocket: 8 * 60 * 60 }; const maxSpeed = { 汽车:300,自行车:60,摩托车:200,飞机:1000,直升机:400,火箭:8 * 60 * 60 };

const sortable = Object.entries(maxSpeed) .sort(([,a],[,b]) => ab) .reduce((r, [k, v]) => ({ ...r, [k]: v }), {}); const sortable = Object.entries(maxSpeed) .sort(([,a],[,b]) => ab) .reduce((r, [k, v]) => ({ ...r, [k ]: v }), {});

console.log(sortable);控制台日志(可排序);

We're running with this answer successfully with this:我们通过这个成功地运行了这个答案:

    const sortWords = () => {
        theWordCount = Object.entries(theWordCount)
          .sort(([, a], [, b]) => a - b)
          .reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
        console.log("OKAY I THINK WE SORTED: " + JSON.stringify(theWordCount));
        createTable();
      };

So now, we need to change this so the large numbers come first on our way down to the small numbers所以现在,我们需要改变这一点,以便大数字在我们下降到小数字的过程中首先出现

https://www.w3schools.com/jsref/jsref_sort.asp https://www.w3schools.com/jsref/jsref_sort.asp

Example Sort numbers in an array in descending order:示例 按降序对数组中的数字进行排序:

const points = [40, 100, 1, 5, 25, 10]; const 点数 = [40, 100, 1, 5, 25, 10]; points.sort(function(a, b){return ba});点排序(函数(a,b){返回ba});

https://www.codegrepper.com/code-examples/javascript/array+sort+from+higher+to+lower+in+js https://www.codegrepper.com/code-examples/javascript/array+sort+from+higher+to+lower+in+js

“array sort from higher to lower in js” Code Answer's “js中数组从高到低排序”代码答案

sorting array from highest to lowest javascriptjavascript by Arqa Arqa javascript javascript 从高到低排序数组
on Mar 25 2020 Comment 14 1 // Sort an array of numbers 2 let numbers = [5, 13, 1, 44, 32, 15, 500] 3 ​ 4 // Lowest to highest 5 let lowestToHighest = numbers.sort((a, b) => a - b); on Mar 25 2020 Comment 14 1 // 对数字数组进行排序 2 let numbers = [5, 13, 1, 44, 32, 15, 500] 3 4 // 最低到最高 5 let minimumToHighest = numbers.sort(( a, b) => a - b); 6 //Output: [1,5,13,15,32,44,500] 7 ​ 8 //Highest to lowest 9 let highestToLowest = numbers.sort((a, b) => ba); 6 //输出:[1,5,13,​​15,32,44,500] 7 8 //从高到低9 lethighestToLowest = numbers.sort((a, b) => ba); 10 //Output: [500,44,32,15,13,5,1] 10 //输出:[500,44,32,15,13,​​5,1]

So I try:所以我尝试:

    const sortWords = () => {
        theWordCount = Object.entries(theWordCount)
          .sort(([, a], [, b]) => b - a)
          .reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
        console.log("OKAY I THINK WE SORTED: " + JSON.stringify(theWordCount));
        createTable();
      };

But it doesn't sort high to low, it does this:但它不会从高到低排序,它是这样做的:

OKAY I THINK WE SORTED: {"10":1,"27":1,"1815":1,"1842":1,"1852":1,"the":18,"and":16,"her":16,"of":15,"in":14,"to":13,"was":9,"a":9,"Ada":8,"an":6,"first":6,"as":6,"Charles":5,"She":4,"out":4,"she":4,"Byron":4,"Lovelace":3,"mathematician":3,"on":3,"Babbage's":3,"Analytical":3,"that":3,"be":3,"by":3,"from":3,"with":3,"Countess":2,"known":2,"for":2,"work":2,"Engine.":2,"beyond":2,"algorithm":2,"carried":2,"such":2,"machine.":2,"is":2,"often":2,"computer":2,"only":2,"other":2,"born":2,"He":2,"thy":2,"my":2,"died":2,"years":2,"Her":2,"remained":2,"interested":2,"him":2,"at":2,"King":2,"Babbage,":2,"\"poetical":2,"led":2,"about":2,"calculating":2,"notes":2,"many":2,"Augusta":1,"King,":1,"(née":1,"Byron;":1,"December":1,"–":1,"November":1,"1852)":1,"English":1,"writer,":1,"chiefly":1,"proposed":1,"mechanical":1,"general-purpose":1,"computer,":1,"recognise":1,"machine":1,"had":1,"applications":1,"pure":1,"calculation,":1,"have":1,"published":1,"intended":1,"As":1,"result,":1,"regarded":1,"programmer.[2][3][4]\n\nAda":1,"child":1,"poet":1,"Lord":1,"Lady":1,"Byron.[5]":1,"All":1,"Byron's":1,"children":1,"were":1,"wedlock":1,"women.[6]":1,"separated":1,"his":1,"wife":1,"month":1,"after":1,"left":1,"England":1,"forever":1,"four":1,"months":1,"later.":1,"commemorated":1,"parting":1,"poem":1,"begins,":1,"\"Is":1,"face":1,"like":1,"mother's":1,"fair":1,"child!":1,"ADA!":1,"sole":1,"daughter":1,"house":1,"heart?\".[7]":1,"Greece":1,"when":1,"eight":1,"old.":1,"mother":1,"bitter":1,"promoted":1,"Ada's":1,"interest":1,"mathematics":1,"logic":1,"effort":1,"prevent":1,"developing":1,"father's":1,"perceived":1,"insanity.":1,"Despite":1,"this,":1,"him,":1,"naming":1,"two":1,"sons":1,"Gordon.":1,"Upon":1,"death,":1,"buried":1,"next":1,"request.":1,"Although":1,"ill":1,"childhood,":1,"pursued":1,"studies":1,"assiduously.":1,"married":1,"William":1,"1835.":1,"made":1,"Earl":1,"1838,":1,"thereby":1,"becoming":1,"Lovelace.\n\nHer":1,"educational":1,"social":1,"exploits":1,"brought":1,"into":1,"contact":1,"scientists":1,"Andrew":1,"Crosse,":1,"Sir":1,"David":1,"Brewster,":1,"Wheatstone,":1,"Michael":1,"Faraday":1,"author":1,"Dickens,":1,"contacts":1,"which":1,"used":1,"further":1,"education.":1,"described":1,"approach":1,"science\"[8]":1,"herself":1,"\"Analyst":1,"(&":1,"Metaphysician)\".[9]\n\nWhen":1,"teenager":1,"(18),":1,"mathematical":1,"talents":1,"long":1,"working":1,"relationship":1,"friendship":1,"fellow":1,"British":1,"who":1,"\"the":1,"father":1,"computers\".":1,"particular":1,"met":1,"June":1,"1833,":1,"through":1,"their":1,"mutual":1,"friend,":1,"private":1,"tutor,":1,"Mary":1,"Somerville.\n\nBetween":1,"1843,":1,"translated":1,"article":1,"Italian":1,"military":1,"engineer":1,"Luigi":1,"Menabrea":1,"engine,":1,"supplementing":1,"it":1,"elaborate":1,"set":1,"notes,":1,"simply":1,"called":1,"\"Notes\".":1,"Lovelace's":1,"are":1,"important":1,"early":1,"history":1,"computers,":1,"containing":1,"what":1,"consider":1,"program—that":1,"is,":1,"designed":1,"Other":1,"historians":1,"reject":1,"this":1,"perspective":1,"point":1,"personal":1,"1836/1837":1,"contain":1,"programs":1,"engine.[10]":1,"also":1,"developed":1,"vision":1,"capability":1,"computers":1,"go":1,"mere":1,"or":1,"number-crunching,":1,"while":1,"others,":1,"including":1,"Babbage":1,"himself,":1,"focused":1,"those":1,"capabilities.[11]":1,"mindset":1,"science\"":1,"ask":1,"questions":1,"Engine":1,"(as":1,"shown":1,"notes)":1,"examining":1,"how":1,"individuals":1,"society":1,"relate":1,"technology":1,"collaborative":1,"tool.[6]\n\nShe":1,"uterine":1,"cancer":1,"age":1,"36.":1} 

How do you sort an object in this fashion from high to low?您如何以这种方式从高到低对对象进行排序?

I tried我试过

.sort(([, b], [, a]) => b - a)

.sort(([b, ], [a, ]) => b - a)

.sort(([, a], [, b]) => b - a)

None of it worked, how do I do what's done in Sorting object property by values but backwards?它都不起作用,我该如何做按值排序对象属性但向后执行的操作?

In the sortWords function, I call;在 sortWords 函数中,我调用; createTable(); but the DOM doesn't update, because render is only called once.但是 DOM 不会更新,因为 render 只被调用一次。

I need to update it somehow, do I call render again somehow?我需要以某种方式更新它,我是否以某种方式再次调用渲染?

The problem is not in the sorting function, that works fine.问题不在于排序功能,它工作正常。 You can see that the order is broken for object properties that consist only of numbers.您可以看到仅由数字组成的对象属性的顺序被破坏。 You can see it in this simple example:你可以在这个简单的例子中看到它:

const t = {a: 1, b: 2, c: 3};
console.log('Order of keys is preserved', t);

const s = {a: 1, b: 2, "10": 3};
console.log('Order of keys is ruined', s);

I am not sure what exactly you can do about it... Some thoughts:我不确定你到底能做些什么......一些想法:

  1. Do not bother with sorting object keys, instead use another more suitable data structure.不要理会对象键的排序,而是使用另一种更合适的数据结构。

  2. If you absolutely need to use object with sorted keys, you could append space to the key when doing the reduce , and then using trim whenever you need to use the key (very stupid idea, but it would work for preserving the key order):如果您绝对需要使用带有排序键的对象,则可以在执行reduce时将空格附加到键,然后在需要使用键时使用trim (非常愚蠢的想法,但它可以用于保留键顺序):

const u = {" a": 1, " b": 2, " 10": 3};
console.log('Ordering of keys preserved', u);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM