Сортировать вложенный словарь по значению в JS - PullRequest
0 голосов
/ 11 ноября 2018

Может кто-нибудь помочь выяснить способ сортировки словаря с другим словарём внутри в JavaScript? Вот как выглядит мой диктат:

{'POS2': {'stegano': 0, 'sum': 200, 'misc': 100, 'web': 0, 'ppc': 0, 'crypto': 0, 'admin': 0, 'vuln': 0, 'forensics': 0, 'hardware': 0, 'reverse': 0, 'recon': 100}, ...}

Я хочу отсортировать его по ключу 'sum', который хранится во вложенном dict. Я могу найти некоторые решения, написанные на python, но задача здесь состоит в том, чтобы достичь той же функциональности в JS. Буду признателен за любую помощь.

Ответы [ 3 ]

0 голосов
/ 11 ноября 2018

Просто получите внутренний объект, используя Object.values, а затем используйте Array.sort, чтобы отсортировать его содержимое. Обратите внимание, что вы не можете сортировать свойства объектов, так как они по умолчанию являются несортированным набором (или, по крайней мере, неправильно описано, как свойства должны быть отсортированы для объекта)

const dict = {
  'POS2': {
    'stegano': 0, 
    'sum': 200, 
    'misc': 100, 
    'web': 0, 
    'ppc': 0, 
    'crypto': 0, 
    'admin': 0, 
    'vuln': 0, 
    'forensics': 0, 
    'hardware': 0, 
    'reverse': 0, 
    'recon': 100
  }, 
  'POS1': {
    'sum': 100
  },
  'POS3': {
    'sum': 250
  }
};

function orderBySubKey( input, key ) {
  return Object.values( input ).map( value => value ).sort( (a, b) => a[key] - b[key] );
}

console.log( orderBySubKey( dict, 'sum' ) );

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

const dict = {
  'POS2': {
    'stegano': 0, 
    'sum': 200, 
    'misc': 100, 
    'web': 0, 
    'ppc': 0, 
    'crypto': 0, 
    'admin': 0, 
    'vuln': 0, 
    'forensics': 0, 
    'hardware': 0, 
    'reverse': 0, 
    'recon': 100
  }, 
  'POS1': {
    'sum': 100
  },
  'POS3': {
    'sum': 250
  }
};

function orderBySubKey( input, key ) {
  return Object.keys( input ).map( key => ({ key, value: input[key] }) ).sort( (a, b) => a.value[key] - b.value[key] );
}

console.log( orderBySubKey( dict, 'sum' ) );

Который дает вам другой вывод, но все же позволяет искать в исходном словаре

0 голосов
/ 11 ноября 2018

Поскольку вы не можете упорядочить объекты по свойству, вам нужно map объекты в массив, а затем отсортировать их. И вы, вероятно, не захотите потерять ключ для каждого вложенного объекта (например, POS2), поэтому вы захотите встроить этот ключ в объект для сохранности.

const obj = {"POS2":{"stegano":0,"sum":2200,"misc":100,"web":0,"ppc":0,"crypto":0,"admin":0,"vuln":0,"forensics":0,"hardware":0,"reverse":0,"recon":100},"POS3":{"stegano":0,"sum":1200,"misc":100,"web":0,"ppc":0,"crypto":0,"admin":0,"vuln":0,"forensics":0,"hardware":0,"reverse":0,"recon":100},"POS4":{"stegano":0,"sum":22,"misc":100,"web":0,"ppc":0,"crypto":0,"admin":0,"vuln":0,"forensics":0,"hardware":0,"reverse":0,"recon":100},"POS5":{"stegano":0,"sum":2001,"misc":100,"web":0,"ppc":0,"crypto":0,"admin":0,"vuln":0,"forensics":0,"hardware":0,"reverse":0,"recon":100}}

// map over the object keys
const out = Object.keys(obj).map(key => {

  // on each iteration return the object with its new key property
  return { ...obj[key], key }

// then sort the array of object by their sums
}).sort((a, b) => a.sum - b.sum);

console.log(out);
0 голосов
/ 11 ноября 2018

Например, у вас есть следующий массив (похожий на ваш массив, но у него меньше свойств для чтения):

let obj = {
    pos1: { sum: 100, name: 'p1' },
    pos2: { sum: 1, name: 'p2' },
    pos3: { sum: 50, name: 'p3' }
};

var result = Object.keys(obj)
    .map(key => { return {key, val: obj[key]}}) // output: unsorted array
    .sort((a, b) => a.val.sum > b.val.sum); 

console.log(result);

и в результате вы увидите:

[ { key: 'pos2', val: { sum: 1, name: 'p2' } },
  { key: 'pos3', val: { sum: 50, name: 'p3' } },
  { key: 'pos1', val: { sum: 100, name: 'p1' } } ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...