用于按多个条件对对象中的数组进行排序的 JavaScript 算法

标签 javascript arrays algorithm object

我正在尝试编写一种算法,根据第一列(名称)分组的每一列的平均值对该表进行排序,以便该表仅显示具有最常见值的行。例如,这是当前表:

unsorted table

排序后应该是这样的:

sorted table

这是我要排序并仅显示最常见表值的数组:

            var testArray = [
            {
                "testName": "10b1",
                "SG": 1.010,
                "pH":6,
                "LEU": "NEG",
                "NIT": "NEG",
                "PRO": "NEG",
                "GLU": "NORM",
                "KET": "NEG",
                "UBG": "NORM",
                "BIL": "NEG",
                "Hb": "NEG"

            },
            {
                "testName": "10b1",
                "SG": 1.010,
                "pH":6,
                "LEU": "NEG",
                "NIT": "NEG",
                "PRO": "NEG",
                "GLU": "NORM",
                "KET": "NEG",
                "UBG": "NORM",
                "BIL": "NEG",
                "Hb": "NEG"
            },
            {
                "testName": "10b1",
                "SG": 1.010,
                "pH":6,
                "LEU": "NEG",
                "NIT": "NEG",
                "PRO": "NEG",
                "GLU": "NORM",
                "KET": "NEG",
                "UBG": "NORM",
                "BIL": "NEG",
                "Hb": "NEG"
            },
            {
                "testName": "10b1",
                "SG": 1.010,
                "pH":6,
                "LEU": "NEG",
                "NIT": "NEG",
                "PRO": "NEG",
                "GLU": "NORM",
                "KET": "NEG",
                "UBG": "NORM",
                "BIL": "NEG",
                "Hb": "NEG"
            },
            {
                "testName": "10b1",
                "SG": 1.010,
                "pH":6,
                "LEU": "NEG",
                "NIT": "NEG",
                "PRO": "NEG",
                "GLU": "NORM",
                "KET": "NEG",
                "UBG": "NORM",
                "BIL": "NEG",
                "Hb": "NEG"
            },
            {
                "testName": "10b1.5",
                "SG": 1.010,
                "pH":6,
                "LEU": "NEG",
                "NIT": "NEG",
                "PRO": "NEG",
                "GLU": 50,
                "KET": "NEG",
                "UBG": "NORM",
                "BIL": "NEG",
                "Hb": 50
            },
            {

                "testName": "10b1.5",
                "SG": 1.010,
                "pH":6,
                "LEU": "NEG",
                "NIT": "NEG",
                "PRO": "NEG",
                "GLU": 50,
                "KET": "NEG",
                "UBG": "NORM",
                "BIL": "NEG",
                "Hb": 50
            },
            {
                "testName": "10b1.5",
                "SG": 1.010,
                "pH":6,
                "LEU": "NEG",
                "NIT": "NEG",
                "PRO": "NEG",
                "GLU": 50,
                "KET": "NEG",
                "UBG": "NORM",
                "BIL": "NEG",
                "Hb": 50
            }
        ];

我尝试使用此算法,但返回的结果与预期结果相去甚远:

  var mf = 1;
        var m = 0;
        var item;
        var count = 1;
        for(let k = 0; k < testArray.length; k++){
            for(let v = 0; v < testArray[k].values.length; v++){
                 current = 1;
                for(j = v; j <= testArray[k].values.length; j++){
                    if(testArray[k].values[v] == testArray[k].values[j]){
                        m++;
                    }

                    if(mf < m){
                        mf=m;
                        item = testArray[k].values[v];
                        testArray[k].values = [];
                    }
                }
                    testArray[k].values[v] = item;

            }

        }

如果有人能给出一些示例算法或问题的解决方案,我将不胜感激:)

最佳答案

您可以遍历数组并创建一个嵌套对象以根据名称对数组进行分组,然后根据键进行分组,最后根据每个键的值进行分组。然后循环遍历 entries这个 counts 嵌套 obj 并根据 mode 创建一个对象每个键的值

这是 counts 对象的样子:

{
    "10b1": {
        "SG": {
            "1.01": 5
        },
        "pH": {
            "6": 5
        },
        "LEU": {
            "NEG": 5
        },
        "NIT": {
            "NEG": 5
        },
        "PRO": {
            "NEG": 5
        },
        "GLU": {
            "NORM": 5
        },
        "KET": {
            "NEG": 5
        },
        "UBG": {
            "NORM": 5
        },
        "BIL": {
            "NEG": 5
        },
        "Hb": {
            "10": 3,
            "NEG": 2
        }
    },
    "10b1.5": {
        "SG": {
            "1.01": 3
        },
        "pH": {
            "6": 3
        },
        "LEU": {
            "NEG": 3
        },
        "NIT": {
            "NEG": 3
        },
        "PRO": {
            "NEG": 3
        },
        "GLU": {
            "50": 3
        },
        "KET": {
            "NEG": 3
        },
        "UBG": {
            "NORM": 3
        },
        "BIL": {
            "NEG": 3
        },
        "Hb": {
            "50": 3
        }
    }
}

这是一个工作片段:

{ testName, ...rest }reduce参数用于 destructuring每个对象到一个单独的 testName 和剩余的属性到一个 rest 对象

var array=[{testName:"10b1",SG:1.01,pH:6,LEU:"NEG",NIT:"NEG",PRO:"NEG",GLU:"NORM",KET:"NEG",UBG:"NORM",BIL:"NEG",Hb:"NEG"},{testName:"10b1",SG:1.01,pH:6,LEU:"NEG",NIT:"NEG",PRO:"NEG",GLU:"NORM",KET:"NEG",UBG:"NORM",BIL:"NEG",Hb:"10"},{testName:"10b1",SG:1.01,pH:6,LEU:"NEG",NIT:"NEG",PRO:"NEG",GLU:"NORM",KET:"NEG",UBG:"NORM",BIL:"NEG",Hb:"NEG"},{testName:"10b1",SG:1.01,pH:6,LEU:"NEG",NIT:"NEG",PRO:"NEG",GLU:"NORM",KET:"NEG",UBG:"NORM",BIL:"NEG",Hb:"10"},{testName:"10b1",SG:1.01,pH:6,LEU:"NEG",NIT:"NEG",PRO:"NEG",GLU:"NORM",KET:"NEG",UBG:"NORM",BIL:"NEG",Hb:"10"},{testName:"10b1.5",SG:1.01,pH:6,LEU:"NEG",NIT:"NEG",PRO:"NEG",GLU:50,KET:"NEG",UBG:"NORM",BIL:"NEG",Hb:50},{testName:"10b1.5",SG:1.01,pH:6,LEU:"NEG",NIT:"NEG",PRO:"NEG",GLU:50,KET:"NEG",UBG:"NORM",BIL:"NEG",Hb:50},{testName:"10b1.5",SG:1.01,pH:6,LEU:"NEG",NIT:"NEG",PRO:"NEG",GLU:50,KET:"NEG",UBG:"NORM",BIL:"NEG",Hb:50}];

const counts = array.reduce((acc, { testName, ...rest }) => {
   if(!acc[testName]) acc[testName] = {};

   let nested = acc[testName];
   
   Object.entries(rest).forEach(([key, value]) => {
    if(!nested[key]) nested[key] = {}
    
    nested[key][value] = nested[key][value] + 1 || 1;
  })
  
  return acc
},{})

const output = Object.entries(counts).map(([testName, count]) => {
  const obj = { testName };
  
  Object.entries(count).forEach(([k, v]) => {
    const mode = Object.keys(v).sort((a, b) => v[b] - v[a])[0];
    obj[k] = mode;
  }, {})
  
  return obj
})

console.log(output)
.as-console-wrapper { max-height: 100% !important; top: 0; }

(没有一个键有一个以上的唯一。因此,对于10b1 名称的Hb 属性,我使用了:"NEG", "10", "NEG", "10", "10" 值 -- 与演示图像相同)

关于用于按多个条件对对象中的数组进行排序的 JavaScript 算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55994617/

相关文章:

java - 将字符串编码为 Base36

algorithm - 具有最大作业时间的调度时间表。

javascript - D3v6 缩放导致指针位置错误

javascript - Electron webview 仅预加载文件 ://protocol is supported when using create-react-app base

javascript - 内部对象函数的 SinonJS calledOnce 或 callCount 问题

javascript - sitefinity 6 - 事件模块错误javascript

c - 将不同数据类型的csv数据保存到C中的数组中

康威的生命游戏 C

c++ - 在 C++ 函数中不使用 static 不修改数组

image - 比较FotoJet和Polarr在图像去雾算法上的区别