TypeScript: сортировка массива 1 по значению indexOf из массива 2 - PullRequest
1 голос
/ 22 января 2020

Я новичок в Typescript / JavaScript, поэтому я уверен, что упускаю что-то простое.

У меня есть массив 2 типов, каждый из которых имеет подмассив 3 - 4 имени:

myArray = [
{
    "type": "abc",
    "names": {
        "Jane Smith": 5,
        "John Doe": 3,
        "Jack Jones": 2
    }
},
{
    "type": "xyz",
    "names": {
        "Jane Smith": 3,
        "John Doe": 7,
        "Jack Jones": 3
    }
}
];

Мне нужно знать, какой основной тип имеет наибольшую общую сумму, и показать это первым. В этом примере «xyz» имеет наибольшее значение ((3 + 7 + 3) против (5 + 3 + 2)). Поэтому я хотел бы отобразить xyz до ab c.

. Я успешно получаю итоговые значения двух и помещаю их в новый массив с именем totalValues:

totalValues = [
{
    "type": "xyz",
    "count": 13            
    }
},
{
    "type": "abc",    
    "count": 10            
    }
}
];

Проблема является то, что мне нужно отсортировать мой исходный массив (myArray) по типу на основе суммы, и я не могу понять это.

let sortedTotalValues = totalValues.sort().reverse();    //highest value first

let sortedGroupNames = null;

sortedGroupNames = myArray.sort((a, b) => {            
    return sortedTotalValues[0].indexOf(a) - sortedTotalValues[0].indexOf(b);
});

Любая помощь будет высоко ценится.

Ответы [ 4 ]

1 голос
/ 22 января 2020

С учетом массива и критериев сортировки вы можете просто указать свои критерии в методе .sort(...) как функцию.

myArray = [
{
    "type": "abc",
    "names": {
        "Jane Smith": 5,
        "John Doe": 3,
        "Jack Jones": 2
    }
},
{
    "type": "xyz",
    "names": {
        "Jane Smith": 3,
        "John Doe": 7,
        "Jack Jones": 3
    }
}
];

myArray.sort((a,b) => {
  let sumA = Object.values(a["names"]).reduce((total, curr) => total + curr, 0);
  let sumB = Object.values(b["names"]).reduce((total, curr) => total + curr, 0);
  
  return sumB -sumA;
});

console.log(myArray);

Примечание : это накладные расходы на пересчет суммы каждый раз, когда выполняется сравнение, это можно улучшить, просто подставив sumA и sumB переменных для получения значения из предварительно вычисленного массива, показанного ниже

myArray = [
{
    "type": "abc",
    "names": {
        "Jane Smith": 5,
        "John Doe": 3,
        "Jack Jones": 2
    }
},
{
    "type": "xyz",
    "names": {
        "Jane Smith": 3,
        "John Doe": 7,
        "Jack Jones": 3
    }
}
];

let total = myArray.map( el => 
  Object.values(el["names"]).reduce((total, curr) => total + curr, 0));
  


myArray.sort((a,b) => {
  let sumA = total[myArray.findIndex( el => el["type"] === a["type"] )];
  let sumB = total[myArray.findIndex( el => el["type"] === b["type"] )];
  
  return sumB - sumA;
});

console.log(myArray);
1 голос
/ 22 января 2020

Полагаю, если вы попытаетесь сначала найти индекс элемента, основанный на свойстве type, с помощью findIndex(), то вы можете поместить sh в нужное место в конечном массиве.

Может быть, вы можете попробовать следующее:

const myArray = [{"type":"abc","names":{"Jane Smith":5,"John Doe":3,"Jack Jones":2}},{"type":"xyz","names":{"Jane Smith":3,"John Doe":7,"Jack Jones":3}}];

const countsInOrder = myArray.map(({type, names}) => ({
  type,
  count: Object.entries(names).reduce((a, [k,v]) => a + v, 0)
})).sort((a,b) => b.count - a.count);

const result = new Array(myArray.length);

myArray.forEach(e => {
  const index = countsInOrder.findIndex(a => a.type === e.type);
  result[index] = e;
});

console.log(result);

Надеюсь, это поможет!

1 голос
/ 22 января 2020
const myArray = [
{
    "type": "abc",
    "names": {
        "Jane Smith": 5,
        "John Doe": 3,
        "Jack Jones": 2
    }
},
{
    "type": "xyz",
    "names": {
        "Jane Smith": 3,
        "John Doe": 7,
        "Jack Jones": 3
    }
}
];
const sum =   (accumulator, currentValue) => accumulator + currentValue;

const total = x=>Object.values(x.names).reduce(sum)

console.log(myArray.sort((a,b)=>(total(b)-total(a))))
[Codepen here][1]


  [1]: https://codepen.io/drGreen/pen/eYmbeze
1 голос
/ 22 января 2020

Попробуйте,

let myArray = [
  {
    "type": "abc",
    "names": {
       "Jane Smith": 5,
       "John Doe": 3,
       "Jack Jones": 2
    }
  },
  {
    "type": "xyz",
    "names": {
       "Jane Smith": 3,
       "John Doe": 7,
       "Jack Jones": 3
    }
  }
];

let modifiedArray = myArray.map(obj => {
  let total = 0;
  for (var property in obj.names) {
    total += obj.names[property];
  }
  return {
    ...obj,
    totalNamesValue: total // Added totalNamesValue which stores the total
  }
});

let sortedArray = modifiedArray.sort((a, b) => b.totalNamesValue - a.totalNamesValue)

console.log(sortedArray);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...