Сортировать объект по ключам с двумя условиями, затем по алфавиту - PullRequest
0 голосов
/ 12 февраля 2020

Я получил объект, который хотел бы отсортировать, учитывая следующие критерии:

  1. Сохранить ключ Keyword в качестве первой записи
  2. Сохранить выбранный ключ в качестве второго
  3. Сохраняйте остальные в алфавитном порядке
const obj = {
  'Keyword': 'keyword',
  'D Rank': 4,
  'D URL': 'https://d.example.com',
  'D Title': 'I am D',
  'A Rank': 1,
  'A URL': 'https://a.example.com',
  'A Title': 'I am A',
  'C Rank': 3,
  'C URL': 'https://c.example.com',
  'C Title': 'I am C',
  'B Rank': 2,
  'B URL': 'https://b.example.com',
  'B Title': 'I am B',
}

Я пробовал следующее:

const sorting = chosenLetter => {
  return (a, b) => {
    const letter = a.split(' ')[0] 

    if (b !== 'Keyword') {
      return a < b ? -1 : 1
    } else {
      if (letter === chosenLetter) {
        return -1
      }
    }
  }
}

const order = Object.keys(obj).sort(sorting('C')).reduce((object, key) => {
  object[key] = obj[key]
  return object
}, {})

console.log(order)

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

Если я передам букву C функции sorting, вывод должен быть:

const obj = {
  'Keyword': 'keyword',
  'C Rank': 3,
  'C URL': 'https://c.example.com',
  'C Title': 'I am C',
  'A Rank': 1,
  'A URL': 'https://a.example.com',
  'A Title': 'I am A',
  'B Rank': 2,
  'B URL': 'https://b.example.com',
  'B Title': 'I am B',
  'D Rank': 4,
  'D URL': 'https://d.example.com',
  'D Title': 'I am D',
}

Любой идеи?

Ответы [ 2 ]

1 голос
/ 13 февраля 2020

Вы можете взять записи и отсортировать по

  • Keyword,
  • выбранная буква
  • первая буква
  • по подстроке.

Получить новый объект из записей.

var obj = {
    'Keyword': 'keyword',
    'C Rank': 3,
    'C URL': 'https://c.example.com',
    'C Title': 'I am C',
    'A Rank': 1,
    'A URL': 'https://a.example.com',
    'A Title': 'I am A',
    'B Rank': 2,
    'B URL': 'https://b.example.com',
    'B Title': 'I am B',
    'D Rank': 4,
    'D URL': 'https://d.example.com',
    'D Title': 'I am D',
},
    order = { Rank: 1, URL: 2, Title: 3 }
    letter = 'D';

obj = Object.fromEntries(Object
    .entries(obj)
    .sort((a, b) =>
        (b[0] === 'Keyword') - (a[0] === 'Keyword') ||
        (b[0][0] === letter) - (a[0][0] === letter) ||
        a[0][0] > b[0][0] || -(a[0][0] < b[0][0]) ||
        order[a[0].slice(2)] - order[b[0].slice(2)]
    ));   

console.log(obj);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 13 февраля 2020

Попробуйте следующее:

const obj = {
  'Keyword': 'keyword',
  'D Rank': 4,
  'D URL': 'https://d.example.com',
  'D Title': 'I am D',
  'A Rank': 1,
  'A URL': 'https://a.example.com',
  'A Title': 'I am A',
  'C Rank': 3,
  'C URL': 'https://c.example.com',
  'C Title': 'I am C',
  'B Rank': 2,
  'B URL': 'https://b.example.com',
  'B Title': 'I am B',
}

const sorting = chosenLetter => {
  return (a, b) => {
    if (a === 'Keyword') {
      return -1;
    }
    if (b === 'Keyword') {
      return 1;
    }
    if (a.startsWith(chosenLetter) && b.startsWith(chosenLetter)) {
      return a === b ? 0 : a < b ? -1 : 1;
    }
    if (a.startsWith(chosenLetter)) {
      return -1;
    }
    if (b.startsWith(chosenLetter)) {
      return 1;
    }
    return a === b ? 0 : a < b ? -1 : 1;
  }
}

const order = Object.keys(obj).sort(sorting('C')).reduce((object, key) => {
  object[key] = obj[key]
  return object
}, {})

console.log(order)
...