分组,排序,合并在包含多个数组的对象中

时间:2019-02-20 10:13:43

标签: javascript python arrays object

我有一个对象,其中包含两个我想用JavaScript处理的数组

original object

{Array1: Array(11), Array2: Array(11)}

Array1:(11) ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'A', 'F', 'C', 'E']

Array2:(11) ['5', '7', '4', '3', '8', '1', '9', '1', '5', '4', '2']

我的问题是:

如何对对象进行分组和排序

after group and sort

然后按值获取前3行,其余的按1行合并:

final result

我对python与SQL结合使用了相同的方法,但是不知道如何仅使用JavaScript来做到这一点,这就是我所做的:

将数据添加到已在SQL中进行分组和排序的数据框中

df1 = collection_condition(Grouped table)

创建新数据框-df2-包含df1的前3个

df2 = df1.iloc[3:]

创建新数据框-df3-包含df1中的其余数据

df3 = df1.iloc[:3]

然后计算df3的总值

rest_total = df3["Array2"].sum()

然后将新行添加到df2

df2.loc[-1] = ["Others", rest_total]
df2.index = df2.index + 1 
df2 = df2.sort_index()

我的计划是:

  1. 尝试按该对象分组(可选-您无需回答这个问题,因为我可以设法将对象分组,但是任何解决方案也都可以)
  2. 必须对该对象进行排序,以便可以像使用python一样对其进行剪切,否则任何建议也将很好。

谢谢

5 个答案:

答案 0 :(得分:0)

要在 JavaScript 中执行此操作,可以将2个数组合并为2个对象的数组,然后使用.sort() method对数组进行排序。

var a1 = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'A', 'F', 'C', 'E'];
var a2 = ['5', '7', '4', '3', '8', '1', '9', '1', '5', '4', '2'];

function sortTable(){
    //Combine the 2 arrays into an array of objects
    //This is assuming that both arrays are of the same length.
    var i, table = [];
    for(i=0;i<a1.length;i++){
        table.push({
            //I'm assuming you are sorting numbers, so I use parseInt()
            "sorting":parseInt(a2[i]), //if a1 is the array you need to sort by, replace a2 with a1.
            "name":a1[i]
        });
    }
    
    //This is where the "magic" (sorting) happens
    table.sort(function(a,b){
        return b.sorting-a.sorting; //descending order
        //return parseInt(a.sorting)-parseInt(b.sorting); //ascending order
    });
    
    //At this point, your table is sorted in descending order
    //table[0] is your highest value.
    
    //EDIT: OOPS forgot to add merging
    var sum = 0;
    var nToDisplay = 3; //change accordingly
    var mergedTable = []; //creating a new table so that you still will have your original table
    for(i=0;i<nToDisplay;i++){
        mergedTable.push(table[i]);
    }
    
    for(i=nToDisplay;i<table.length;i++){
        sum+=table[i].sorting;
    }
    mergedTable.push({
        "sorting":sum,
        "name":"OTHERS"
    });

    //FOR OUTPUT
    out='<div><b>MERGED TABLE</b><br>';
    for(i=0;i<mergedTable.length;i++){
        out += mergedTable[i].name+" | "+mergedTable[i].sorting+"<br>";
    }
    out+="</div><hr />";
    
    out+='<div><b>ORIGINAL TABLE</b><br>';
    for(i=0;i<table.length;i++){
        if(i<3) out+="<b>";
        out += table[i].name+" | "+table[i].sorting+"<br>";
        if(i<3) out+="</b>";
    }
    out+="</div>";
    
    document.getElementById("out").innerHTML = out;
}
<h3>Array values:</h3>
<div>
  ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'A', 'F', 'C', 'E']</div>
<div>
  ['5', '7', '4', '3', '8', '1', '9', '1', '5', '4', '2']</div>
<div>
  <input type="button" value="Sort my table!" onclick="sortTable()"/>
</div>

<div><hr /></div>

<div id="out"></div>

答案 1 :(得分:0)

您可以对数据进行转置,分组,排序,以获得前三个值和其他值的总和,再次转置并分配回对象。

const
    transpose = (r, a) => a.map((v, i) => [...(r[i] || []), v]),
    group = (r, a) => {
        var temp = r.find(v => v[1] === +a[1]);
        if (!temp) {
            r.push([a[0], +a[1]]);
        } else {
            temp[1] += +a[1];
        }
        return r;
    }

var data = { Array1: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'A', 'F', 'C', 'E'], Array2: ['5', '7', '4', '3', '8', '1', '9', '1', '5', '4', '2'] },
    temp = Object
        .values(data)
        .reduce(transpose, [])
        .reduce(group, [])
        .sort(({ 1: a }, { 1: b }) => b - a)
        .reduce((r, a, i) => r.concat([i < 4 ? a : ['OTHERS', r.pop()[1] + a[1]]]), [])
        .reduce(transpose, []);

[data.Array1, data.Array2] = temp;

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

答案 2 :(得分:0)

在给定数组的情况下, Python 中的一个可能选项:

ari1 = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'A', 'F', 'C', 'E']
ari2 = ['5', '7', '4', '3', '8', '1', '9', '1', '5', '4', '2']

构建一个字典以计算每个字母的总和:

from collections import defaultdict

tmp = defaultdict(int)
for a, b in zip(ari1, ari2):
 tmp[a] += int(b)

print(tmp)
#=> defaultdict(<class 'int'>, {'A': 6, 'B': 7, 'C': 8, 'D': 3, 'E': 10, 'F': 6, 'G': 9})

然后建立一个排序列表,因为字典不保持顺序:

sorted_tmp = sorted([ [k, v] for k,v in tmp.items() ], key = lambda x: -x[1] )
print(sorted_tmp)
#=> [['E', 10], ['G', 9], ['C', 8], ['B', 7], ['A', 6], ['F', 6], ['D', 3]]

然后切片列表并构建最终结果:

res = sorted_tmp[0:3] + [[ 'others', sum([x[1] for x in sorted_tmp[3:]]) ]]
#=> [['E', 10], ['G', 9], ['C', 8], ['others', 22]]

答案 3 :(得分:0)

您可以按照以下步骤操作。

  1. 使用map()获取包含数字和字母的objects数组。
  2. 使用numsort()的基础上对对象数组进行排序
  3. 使用slice()
  4. 获取3以下数组的一部分
  5. 使用reduce()
  6. 添加该零件的值
  7. 最后使用concat()将缩减的部分(第3行之后的部分)与前3个元素连接起来
  8. 然后使用reduce()
  9. 对象数组更改为两个数组的对象

let obj = {arr1:['A', 'B', 'C', 'D', 'E', 'F', 'G', 'A', 'F', 'C', 'E'],arr2:['5', '7', '4', '3', '8', '1', '9', '1', '5', '4', '2']};
let temp = obj.arr2.map((num,i) => ({num:num,letter:obj.arr1[i]})).sort((a,b) => b.num - a.num);
/**/
let rowNumber = 3;
let merged = temp.slice(0,3).concat(temp.slice(3).reduce((ac,item) => ({num:Number(item.num) + Number(ac.num), letter:ac.letter + item.letter})));
merged = merged.reduce((ac,a) => {
  ac.arr1.push(a.letter)
  ac.arr2.push(a.num)
  return ac;
},{arr1:[],arr2:[]})
console.log(merged);

答案 4 :(得分:0)

    var a = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'A', 'F', 'C', 'E']
var b = ['5', '7', '4', '3', '8', '1', '9', '1', '5', '4', '2']

var hsh = creteHashFromArrays(a, b)
hsh = sortArrayDescending(hsh)
hsh = iterateHash(hsh)
console.log(hsh)

function creteHashFromArrays(a, b) {
    var h = {};
    for(ele in a) {
        if (a[ele] in h) {
            h[a[ele]] = h[a[ele]] + parseInt(b[ele])
        } else {
            h[a[ele]] = parseInt(b[ele])
        }
    }
    return h;
}

function sortArrayDescending(h) {
    var r = {}
    Object.keys(h).sort(function(a,b){return h[b] - h[a]}).map(k => r[k] = h[k])
    console.log(r)
    return r;
}

function iterateHash(r) {
    result = {}
    var x = Object.keys(r)
    for(i in x){

        if (i < 3) {
            result[x[i]] = r[x[i]]
        } else {
            if ("others" in result) {
                result["others"] = parseInt(result["others"]) + parseInt(r[x[i]])
            } else {
                result["others"] = parseInt(r[x[i]])
            }
        }
    }
    var obj = {
        "array_one": Object.keys(result),
        "array_two":  Object.values(result)
    }
    console.log(obj)
    return result;
}

Fiddle Example