Группировать, сортировать, объединять в объект, который содержит несколько массивов - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть объект, который содержит 2 массива, которые я хочу обработать с помощью 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']

Мой вопрос:

Как я могу сгруппировать и отсортировать этот объект так, чтобы он был таким

после группировки и сортировки

Затем получить первые 3 строки по значению с остальными, которые объединеныв 1 строке, например:

final result

Я сделал то же самое с Python в сочетании с SQL, но не знаю, как сделать то же самое, используя только JavaScript, вот что я сделал:

Добавить данные во фрейм данных, которые уже сгруппированы и отсортированы в SQL

df1 = collection_condition(Grouped table)

Создать новый фрейм данных - df2, содержащий первые три из df1

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. Попробуйте сгруппировать по этому объекту (необязательно - вам не нужно отвечать на этот вопрос, так как мне удастся иметь роuped объект, но любое решение было бы также хорошо)
  2. Нужно отсортировать этот объект, чтобы я мог вырезать его, как я сделал с python, или любое предложение будет также хорошо.

Спасибо

Ответы [ 5 ]

0 голосов
/ 20 февраля 2019
    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;
}

Пример скрипки

0 голосов
/ 20 февраля 2019

Вы можете выполнить следующие шаги:

  1. использовать map(), чтобы получить массив objects, который содержит и цифру и букву.
  2. Сортировать массив объекта пооснование num, используя sort()
  3. Получить часть массива ниже 3, используя slice()
  4. Добавьте значения этой части, используя reduce()
  5. Наконецсоедините уменьшенную часть (часть после строки 3) с первыми 3 элементами, используя concat()
  6. , а затем измените массив объектов на объект из двух массивов , используяreduce()

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);
0 голосов
/ 20 февраля 2019

Вы можете транспонировать данные, группировать их, сортировать и получать три верхних значения и суммированные другие значения, снова транспонировать и присваивать объекту обратно.

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; }
0 голосов
/ 20 февраля 2019

Один из возможных вариантов в 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']

Создайте dict для расчета суммы для каждой буквы:

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]]
0 голосов
/ 20 февраля 2019

Чтобы сделать это в JavaScript , вы можете объединить 2 массива в массив из 2 объектов, а затем отсортировать массивы, используя метод .sort() .

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...