Получить уникальные значения из массива объектов - PullRequest
1 голос
/ 26 марта 2020
[
  {key1 : 'sometext'},
  {key2 : 'sometext'},
  {key1 : 'sometext'},
  {key3 : 'sometext'},
]

Из приведенного выше кода мне нужно получить следующие результаты, удалив объекты, содержащие одинаковые ключи

[
  {key1 : 'sometext'},
  {key2 : 'sometext'},
  {key3 : 'sometext'},
]

Заранее спасибо.

Ответы [ 4 ]

3 голосов
/ 26 марта 2020

С loda sh вы можете использовать _.uniqBy() и вернуть один ключ каждого объекта:

const arr = [{"key1":"sometext"},{"key2":"sometext"},{"key1":"sometext"},{"key3":"sometext"}]

const result = _.uniqBy(arr, o => _.keys(o)[0])

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Используя ваниль JS, если вам все равно, будет ли использован второй элемент (дубликат, вы можете объединить все элементы в один объект) (это удалит первый дубликат), получит записи и отобразит обратно массив объектов:

const arr = [{"key1":"sometext"},{"key2":"sometext"},{"key1":"sometext"},{"key3":"sometext"}]

const result = Object.entries(Object.assign({}, ...arr))
  .map(([k, v]) => ({ [k]: v }))

console.log(result)
2 голосов
/ 26 марта 2020

_.uniqBy(data, _.findKey);

Объяснение:

В _.uniqueBy() вам нужно указать, по какому значению вы хотите получить уникальность, либо вы передаете строку как атрибут (значение этого атрибута будет использоваться для определения уникальности), или вы передаете обратный вызов, который вернет значение, и это значение будет считаться для оценки уникальности. В случае, если значение, по которому мы определим уникальность, является простым и нативным значением, _.uniqueBy() является лучшим выбором, поэтому вам не нужно сравнивать вручную (что вам нужно сделать, если ваше значение является сложным объектом и по У многих ключей уникальность определяется). В нашем случае это просто object key, который может быть либо string, либо symbol. Таким образом, часть капризона мы можем допустить на lodash с _uniqueBy

В нашем случае, если мы может вернуть единственный ключ (это должен быть ровно 1, иначе ни один из лог c не будет работать) каждого объекта, _.uniqueBy() может сделать дальше, поэтому в основном наша цель - передать обратный вызов, который вернет единственный ключ , мы можем просто передать обратный вызов для оценки этого, например: e => _.keys(e)[0]

Теперь _.findkey принимает объект в качестве первого аргумента и достоверность возвращаемого значения, если это правда, тогда он вернет этот ключ ( в отличие от возврата этой сущности, такой как _.find), поэтому, если вы не передадите обратный вызов, для обработки этого случая автоматически присваивается обратный вызов по умолчанию со значением a => a. это означает, что он будет проверять истинность каждой сущности (в данном случае ключ), и, очевидно, ключ должен быть истинным значением, поэтому он будет возвращать саму первую сущность (здесь первый ключ для _.findKey), следовательно, передавая Обтекание обратного вызова findKey только с одним аргументом, таким как a => _.findKey(a) эквивалентно передаче обратного вызова _.findKey, мы можем сделать его более простым, и _.uniqueBy(data, _.findKey) сделает эту работу.

Давайте получим фрагмент:

let data=[{key1:"sometext"},{key2:"sometext"},{key1:"sometext"},{key3:"sometext"}];

let res = _.uniqBy(data, _.findKey);

console.log('Unique Result: ', res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
1 голос
/ 26 марта 2020

Это использует чистый javascript, не используя loada sh

const arr = [
  {key1 : 'sometext'},
  {key2 : 'sometext'},
  {key1 : 'sometext'},
  {key3 : 'sometext'},
];

const result = arr.reduce((acc, item) => {

   if (!acc.find(x => Object.keys(x).sort().toString() == Object.keys(item).sort().toString() )) {
      acc.push(item)
   }
   
   return acc;
}, []);

console.log(result);
0 голосов
/ 26 марта 2020

Простое и быстрое решение. Не много итераций.

const data = [
  { key1: "sometext" },
  { key2: "sometext" },
  { key1: "sometext" },
  { key3: "sometext" }
];
const uniqueElementsBy = (arr, fn) =>
  arr.reduce((acc, v) => {
    if (!acc.some(x => fn(v, x))) acc.push(v);
    return acc;
  }, []);

const isEqual = (x, y) => JSON.stringify(x) == JSON.stringify(y);
console.log(uniqueElementsBy(data, isEqual));

// For complex solution

const isEqual2 = (x, y) => {
  const keys1 = Object.keys(x);
  const keys2 = Object.keys(y);

  if (keys1.length != keys2.length) return false;
  return !keys1.some(key => x[key] != y[key]);
};
console.log(uniqueElementsBy(data, isEqual2));
const data2 = [
  { key2: "sometext", key1: "sometext" },
  { key2: "sometext" },
  { key1: "sometext", key2: "sometext" },
  { key3: "sometext" }
];
console.log(uniqueElementsBy(data2, isEqual2));

const data3 = [
  { key1: "sometext" },
  { key2: "sometext" },
  { key1: "sometext", key2: "sometext" },
  { key3: "sometext" }
];
console.log(uniqueElementsBy(data3, isEqual2));
.as-console-row {color: blue!important}
...