web-dev-qa-db-ja.com

JavaScriptを使用してオブジェクトの重複する値を見つける

私が抱えている問題を解決しようとしています。次のように、オブジェクトを含む配列があります。

var array = [
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Hannah Reed",
    Country: "Scottland",
    Age: 23
  },
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Robert Landley",
    Country: "England",
    Age: 84
  },
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Robert Landley",
    Country: "England",
    Age: 84
  }
];

検索する値に基づいて、値が重複しているオブジェクトを取得したいと考えています。つまり、 "name"と "age"の値が重複しているが "country"は含まれていないオブジェクトを取得したいので、次のようになります。

[
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Robert Landley",
    Country: "England",
    Age: 84
  },
  {
    name: "Steven Smith",
    Country: "England",
    Age: 35
  },
  {
    name: "Robert Landley",
    Country: "England",
    Age: 84
  }
];

しようとしていた場合

array.forEach(function(name, age){
  if(array.name == name || array.age == age){
    console.log(the result)
}
})

しかし、それはオブジェクトの値がそれら自身と等しいかどうかをチェックするだけです。

誰かが私を助けてくれますか?

6
Aborgh

2 reduceを使用できます。最初の方法は、アレイをグループ化することです。 2つ目は、複数の要素を持つグループのみを含めることです。

var array = [{"name":"Steven Smith","Country":"England","Age":35},{"name":"Hannah Reed","Country":"Scottland","Age":23},{"name":"Steven Smith","Country":"England","Age":35},{"name":"Robert Landley","Country":"England","Age":84},{"name":"Steven Smith","Country":"England","Age":35},{"name":"Robert Landley","Country":"England","Age":84}]

var result = Object.values(array.reduce((c, v) => {
  let k = v.name + '-' + v.Age;
  c[k] = c[k] || [];
  c[k].Push(v);
  return c;
}, {})).reduce((c, v) => v.length > 1 ? c.concat(v) : c, []);

console.log(result);
5
Eddie

私が思いついた簡単な答え:

   
let result = [];

for(let item of array)
{
    for(let checkingItem of array)
    {
      if(array.indexOf(item) != array.indexOf(checkingItem) &&
        (item.name == checkingItem.name || item.Age == checkingItem.Age))
      {
        if(result.indexOf(checkingItem) == -1)
        {
          result.Push(checkingItem);
        }

      }
   }
}

console.log(result);
3

以下のスニペットを試してください。独自の要素(内部ループ)を介して配列をループします。 1番目のif条件は同じ要素をチェックし(出力にはそれを望まない)、2番目のifは必要な条件一致を実行して重複オブジェクトを識別します。

var array = [
        {
                name: "Steven Smith",
                Country: "England",
                Age: 35
        },
        {
                name: "Hannah Reed",
                Country: "Scottland",
                Age: 23
        },
        {
                name: "Steven Smith",
                Country: "England",
                Age: 35
        },
        {
                name: "Robert Landley",
                Country: "England",
                Age: 84
        },
        {
                name: "Steven Smith",
                Country: "England",
                Age: 35
        },
        {
                name: "Robert Landley",
                Country: "England",
                Age: 84
        }
];

for(let obj of array){
        for(let ele of array){
                if(obj==ele)
                        continue;
                if(ele.name===obj.name && ele.age===obj.age){
                        console.log(obj);
                        break;
                }
        }
}
2
hnDabhi

ここに私が指摘する代替の解決策があります

let array      = getData();                       // sets up data array
let duplicates = array.filter(duplicatesOnly);    // filter out duplicates

console.log( duplicates );                        // output to console



/* ============================================================================= */


// Returns true/false based on a duplicate object being found   
function duplicatesOnly(v1, i1, self) {
  let ndx = self.findIndex(function(v2, i2) {
    // make sure not looking at the same object (using index to verify)
    // use JSON.stringify for object comparison
    return (i1 != i2 && JSON.stringify(v1) == JSON.stringify(v2))
  })
  return i1 != ndx && ndx != -1
}


// Use function hoisting to place trivial code at the bottom of example
function getData() {
  return [{
      name: "Steven Smith",
      Country: "England",
      Age: 35
    },
    {
      name: "Hannah Reed",
      Country: "Scottland",
      Age: 23
    },
    {
      name: "Steven Smith",
      Country: "England",
      Age: 35
    },
    {
      name: "Robert Landley",
      Country: "England",
      Age: 84
    },
    {
      name: "Steven Smith",
      Country: "England",
      Age: 35
    },
    {
      name: "Robert Landley",
      Country: "England",
      Age: 84
    }
  ];
}

利点

  • コードの中心は3行
  • コードは明確です
  • メンテナンスが簡単

費用

  • パフォーマンス
    • JSON.stringifyは、各反復で2つのオブジェクトに対して実行されています(非常に高価)
    • 複雑さ:O(N ^ 2)-配列が大きいほど遅くなる可能性があります

ノート


  • JSON.stringifyはキーの順序に基づいて文字列を作成する可能性があるため、オブジェクトが同じキー/値を持っている場合でも、オブジェクトを比較するときの順序が要因になる可能性があります-これは利点またはコストと見なされる可能性があります
  • これは、filterfindIndexを使用した例であり、効率化に重点が置かれていませんでした。キャッシングを使用してJSON.stringify一度、またはよりカスタマイズされたもので完全に回避します。
1
BotNet