如何在JavaScript中标记对象数组中具有重复属性的第一个对象

时间:2018-04-10 18:45:18

标签: javascript arrays json

我有一个这样的数组:

 var myArray = [
    {id: 1, entry_id: 1, name: 'test', email: 'foo@bar.com'},
    {id: 2, entry_id: 1, name: 'test', email: 'bar@foo.com'},
    {id: 3, entry_id: 2, name: 'test', email: 'foo@bar.com'},
    {id: 4, entry_id: 2, name: 'test', email: 'bar@foo.com'},
    {id: 5, entry_id: 3, name: 'test', email: 'joe@ocean.com'},
    {id: 6, entry_id: 3, name: 'test', email: 'foo@bar.com'},
    {id: 7, entry_id: 3, name: 'test', email: 'foo@bar.com'},
 ];

我需要标记哪个元素首先等于' entry_id'和' name',所以结果应该是这样的:

 [
    {id: 1, entry_id: 1, name: 'test', email: 'foo@bar.com', isFirst:true},
    {id: 2, entry_id: 1, name: 'test', email: 'bar@foo.com', isFirst:false},
    {id: 3, entry_id: 2, name: 'test', email: 'foo@bar.com', isFirst:true},
    {id: 4, entry_id: 2, name: 'test', email: 'bar@foo.com', isFirst:false},
    {id: 5, entry_id: 3, name: 'test', email: 'joe@ocean.com', isFirst:true},
    {id: 6, entry_id: 3, name: 'test', email: 'foo@bar.com', isFirst:false},
    {id: 7, entry_id: 3, name: 'test', email: 'foo@bar.com', isFirst:false},
 ];

我已经尝试过的事情:

function updateArray() {
    myArray.forEach((item, i) => {
      item.isFirst = false;
      myArray.forEach((item2, j) =>{
        if (item.entry_id == item2.entry_id && item.name == item2.name && i < j ) {
          item.isFirst = true;
        } else if (!item.isFirst) {
          item.isFirst = false;
      }
   })
 })
 return myArray;
}

我得到的结果是下一个:

 [
    {id: 1, entry_id: 1, name: 'test', email: 'foo@bar.com', isFirst:true},
    {id: 2, entry_id: 1, name: 'test', email: 'bar@foo.com', isFirst:false},
    {id: 3, entry_id: 2, name: 'test', email: 'foo@bar.com', isFirst:true},
    {id: 4, entry_id: 2, name: 'test', email: 'bar@foo.com', isFirst:false},
    {id: 5, entry_id: 3, name: 'test', email: 'joe@ocean.com', isFirst:true},
    {id: 6, entry_id: 3, name: 'test', email: 'foo@bar.com', isFirst:true},
    {id: 7, entry_id: 3, name: 'test', email: 'foo@bar.com', isFirst:false},
 ];

是否有最佳方法而不是使用2个循环?

谢谢你的帮助!

链接到jsfiddle: https://jsfiddle.net/88p5p5oj/30/

5 个答案:

答案 0 :(得分:3)

您可以使用哈希表在单个循环中收集所需组的第一个标记。

&#13;
&#13;
Copy-RDSDBSnapshot -SourceDBSnapshotIdentifier $dBSnapshotArn `
                   -SourceRegion 'us-east-1' `
                   -TargetDBSnapshotIdentifier $targetSnapshotName `
                   -KmsKeyId 'arn:aws:kms:us-west-2:xxxxx:key/xxxxx' `
                   -CopyTag $true -OptionGroupName 'myOptionGroup' `
                   -Region 'us-west-2'  # <-- new line
&#13;
var array = [{ id: 1, entry_id: 1, name: 'test', email: 'foo@bar.com' }, { id: 2, entry_id: 1, name: 'test', email: 'bar@foo.com' }, { id: 3, entry_id: 2, name: 'test', email: 'foo@bar.com' }, { id: 4, entry_id: 2, name: 'test', email: 'bar@foo.com' }, { id: 5, entry_id: 3, name: 'test', email: 'joe@ocean.com' }, { id: 6, entry_id: 3, name: 'test', email: 'foo@bar.com' }, { id: 7, entry_id: 3, name: 'test', email: 'foo@bar.com' }],
    keys = ['entry_id', 'name'],
    hash = Object.create(null);

array.forEach(o => {
    var key = keys.map(k => o[k]).join('|');
    o.isFirst = !hash[key];
    hash[key] = true;
});

console.log(array);
&#13;
&#13;
&#13;

答案 1 :(得分:2)

找到并设置第一个匹配后,只需返回myArray即可。或者您可以返回找到它的数组索引并使用它。

如果您需要在每个对象上设置isFirst属性(因为它在该对象中不存在),并且您希望在循环中完成,那么只需将代码更改为以下内容:< / p>

function updateArray() {
    var foundFirst = false;
    myArray.forEach((item, i) => {
      item.isFirst = false;
      myArray.forEach((item2, j) =>{
        if (!foundFirst && item.entry_id == item2.entry_id && item.name == item2.name && i < j ) {
          item.isFirst = true;
          foundFirst = true;
        } else {
          item.isFirst = false;
      }
   })
 })
 return myArray;
}

答案 2 :(得分:2)

此方法使用名为visited的对象来跟踪已检查的元素。

此示例有两个名为“Jenny Block”的对象

var myArray = [    {id: 1, entry_id: 1, name: 'test', email: 'foo@bar.com'},    {id: 2, entry_id: 1, name: 'test', email: 'bar@foo.com'},    {id: 3, entry_id: 2, name: 'test', email: 'foo@bar.com'},    {id: 4, entry_id: 2, name: 'test', email: 'bar@foo.com'},    {id: 5, entry_id: 3, name: 'Joe Ocean', email: 'joe@ocean.com'},    {id: 6, entry_id: 3, name: 'Jenny Block', email: 'foo@bar.com'},    {id: 7, entry_id: 3, name: 'Jenny Block', email: 'foo@bar.com'}, ],
    visited = {};
   
myArray.forEach(c =>  {
  var key = `${c.entry_id}|${c.name}`;
  c.isFirst = !visited[key];
  visited[key] = true
});
console.log(myArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 3 :(得分:0)

尝试将您的功能更新为此类.. 免责声明..这确实假设您的json将被订购。

const myArray = [
  {id: 1, entry_id: 1, name: 'test', email: 'foo@bar.com'},
  {id: 2, entry_id: 1, name: 'test', email: 'bar@foo.com'},
  {id: 3, entry_id: 2, name: 'test', email: 'foo@bar.com'},
  {id: 4, entry_id: 2, name: 'test', email: 'bar@foo.com'},
  {id: 5, entry_id: 3, name: 'Joe Ocean', email: 'joe@ocean.com'},
  {id: 6, entry_id: 3, name: 'Jenny Block', email: 'foo@bar.com'},
  {id: 7, entry_id: 3, name: 'Jenny Block', email: 'foo@bar.com'},
];

function updateArray() {
  var prevItem = "";
  myArray.forEach((item, i) => {
       item.isFirst = item.entry_id != prevItem;
       prevItem = item.entry_id;
  });
  return myArray;
}

console.log(updateArray());

答案 4 :(得分:0)

您可以将Array.map()与辅助对象一起使用来迭代您的数组。对于数组中存在的每个元素isFirstfalse。如果某个元素不在helper对象中,请将其添加到帮助程序,并将isFirst设置为true

使用object spreadObject.assign()克隆原始对象,然后添加isFirst

const myArray = [
  {id: 1, entry_id: 1, name: 'test', email: 'foo@bar.com'},
  {id: 2, entry_id: 1, name: 'test', email: 'bar@foo.com'},
  {id: 3, entry_id: 2, name: 'test', email: 'foo@bar.com'},
  {id: 4, entry_id: 2, name: 'test', email: 'bar@foo.com'},
  {id: 5, entry_id: 3, name: 'Joe Ocean', email: 'joe@ocean.com'},
  {id: 6, entry_id: 3, name: 'Jenny Block', email: 'foo@bar.com'},
  {id: 7, entry_id: 3, name: 'Jenny Block', email: 'foo@bar.com'},
];

const helper = Object.create(null);
const result = myArray.map(function(o) {
  const key = `${o.entry_id}-${o.name}`;
  const isFirst = helper[key] ? false : (helper[key] = true);

  return { ...o,  isFirst };
});

console.log(result);