从对象数组获取唯一值

时间:2020-03-26 14:18:48

标签: javascript arrays lodash javascript-objects

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

从上面的代码中,我需要获得如下结果,删除包含相同键的对象

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

谢谢。

4 个答案:

答案 0 :(得分:3)

使用lodash,您可以使用_.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)

答案 1 :(得分:2)

_.uniqBy(data, _.findKey);

说明:

_.uniqueBy()中,您需要告诉您要导出唯一性的值是什么,您可以将字符串作为属性传递(该属性的值将用于确定唯一性),或者传递回调它将返回一个值,并将该值视为评估唯一性。如果我们将要确定唯一性的值是原始值和本机值,那么_.uniqueBy()是一个更好的选择,因此您不需要手动比较(如果您的值是一个复杂的对象,则必须这样做)并根据许多键确定唯一性)。在我们的情况下,它很简单object key,可以是stringsymbol,因此,可以使用lodash_uniqueBy放在_.uniqueBy()的caparison部分

在我们的例子中,如果我们可以返回每个对象的唯一键(必须精确地为1,否则任何逻辑都不起作用),e => _.keys(e)[0]可以做得更多,所以基本上我们的目标是传递一个将返回唯一键的回调。我们可以简单地传递一个回调来进行评估,例如:_.findkey

现在,_.find将对象作为返回值的真实性和第一个参数,如果是真实性,它将返回该键(与像a => a这样的实体不同),所以如果如果不传递回调,则会自动分配默认回调_.findKey来处理这种情况。这意味着它将检查每个实体的真实性(在这种情况下为键),显然,键必须是真实值,因此它将返回第一个实体本身(此处为a => _.findKey(a)的第一个键),因此传递仅包含一个参数(例如_.findKey的回调包装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>
<h1>Blogs</h1>
<fieldset>
    <label>Keyword Search</label>
    <input type="text" @bind="keywordValue" @bind:event="oninput" @onkeypress="KeywordEnterPressed"/>
    <button type="submit" @onclick="SearchBlogs">Search</button>
</fieldset>

答案 2 :(得分:1)

这是使用纯JavaScript,而不是使用loadash

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);

答案 3 :(得分:0)

简单快速的解决方案。迭代次数不多。

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}