Сортировка массива объектов на основе свойства как регулярное выражение - PullRequest
0 голосов
/ 31 января 2019

Если у меня есть массив слов ...

const a = ["abc", "abcd", "xyz"]

, и я хочу отсортировать этот массив и отфильтровать его по шаблону (например, "ab"), тогда я могу использовать filter и regexвот так ... [давая мне массив элементов, который имеет "ab" в начале каждого элемента в массиве "

let value = "abc";
let regex = new RegExp(`^${value}`, `i`);
const sorted = a.sort().filter(v => regex.test(v));

Однако, как насчет этого же принципа, но вместо массиваэлементы, эти элементы являются объектами в массиве, например ...

const b = [
{text: "abc", color: "blue"},
{text: "abcd", color: "red"},
{text: "xyz", color: "yellow"}
]

Ответы [ 4 ]

0 голосов
/ 31 января 2019

Вы можете создать функцию, которая принимает входной массив, строку и функцию, которая принимает текущее значение .findIndex() для сортировки результирующего массива и значения строки, которое передается конструктору RegExp, где параметры функции могутбыть настроен так, чтобы использовать присвоение деструктурирования для соответствия определенному имени свойства во входном массиве объектов, с .splice(), используемым для удаления соответствующего элемента из массива, или остатка от входного массива.

const regexSort = (arr, value, fn) => {
  const res = [];
  for (let i; (i = arr.findIndex(v => fn(v, value))) > -1; res.push(arr.splice(i, 1)[0]));
  return [...res, ...arr];
}

const a = ["abc", "abcd", "xyz", "abcdef", "qrst", "abcg"];

const b = [
  {text: "abc", color: "blue"},
  {text: "abcd", color: "red"},
  {text: "xyz", color: "yellow"},
  {text: "abcdef", color: "gold"},
  {text: "qrst", color: "green"},
  {text: "abcg", color: "brown"}
];

let value = "abc";
// array of strings
console.log(
  regexSort(a, value, (key, value) => new RegExp(`^${value}`, `i`).test(key))
);
// array of objects, destructure `text` property assign to `key`
console.log(
  regexSort(b, value, ({text: key}, value) => new RegExp(`^${value}`, `i`).test(key))
);
0 голосов
/ 31 января 2019

вам нужно указать .sort(), какое свойство вы хотите отсортировать, и передать v.text в регулярное выражение:

const b = [{
    text: "abc",
    color: "blue"
  },
  {
    text: "abcd",
    color: "red"
  },
  {
    text: "xyz",
    color: "yellow"
  }
]

let value = "abc";
let regex = new RegExp(`^${value}`, `i`);
const sorted = b.sort((a, b) => {
  if (a.text > b.text)
    return 1;
  if (a.text < b.text)
    return -1;
  return 0
}).filter(v => regex.test(v.text));

console.log(sorted);
0 голосов
/ 31 января 2019

Сначала вы должны filter() массив, основанный на regex (нет необходимости сортировать элементы, которые будут отфильтрованы позднее), а затем отсортировать его с помощью String :: localeCompare ()

const arr = [
    {text: "abc", color: "blue"},
    {text: "abcd", color: "red"},
    {text: "xyz", color: "yellow"}
];

let value = "abc";
let regex = new RegExp(`^${value}`, `i`);

const sortedArr = arr.filter(x => regex.test(x.text)).sort(
    (a, b) => a.text.localeCompare(b.text)
);

console.log(sortedArr);
0 голосов
/ 31 января 2019

(Фильтрация первой может избежать сортировки большого количества значений, которые будут отбрасываться фильтром)

const b = [
  {text: "abcf", color: "white"},
  {text: "abc", color: "blue"},
  {text: "xyz", color: "yellow"},
  {text: "abcd", color: "red"},
  {text: "abcz", color: "green"},
];


let value = "abc";
let regex = new RegExp(`^${value}`, `i`);

const sorted = b
  .filter(item => regex.test(item.text))
  .sort((a, b) => a.text.localeCompare(b.text));
  
 console.log(sorted);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...