0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

配列の重複するオブジェクトを取り除きつつ数えたい

Posted at

配列に重複するオブジェクトがある場合に、重複するオブジェクトを取り除きつつも、オブジェクト毎にいくつ重複するオブジェクトがあったか知りたいことがあります。

重複するオブジェクトの数を count プロパティに代入したい場合は以下のように書けます。condition はオブジェクトが重複する条件を定義します。

Array.protptype.reduce((a, b) => {
    const duplicated = a.find(/* condition */)
    duplicated ? duplicated.count += 1 : a.push({...b, count: 1})
    return a
}, [])

また、特に連続する重複するオブジェクトのみを対象とする場合は以下のように書けます。
予め重複するオブジェクトが連続することが分かっている場合は、こちらの方が計算量が線形なのでよいと思います。

Array.protptype.reduce((a, b) => {
    const last = a[a.length - 1]  // a が [] の場合は last は undefined になります。
    last && (/* condition... */) ? last.count += 1 : a.push({...b, count: 1})
    return a
}, [])

具体的な使い方をみていきます。例えば、以下のようなデータがある場合を想定します。

type person = {
    name: string,
    age: number
}

const data: person[] = [
    {name: "aaa", age: 18,},
    {name: "bbb", age: 20,},
    {name: "bbb", age: 21,},
    {name: "ccc", age: 21,},
    {name: "bbb", age: 20,},
]

nameage のいずれも重複するオブジェクトを取り除きつつ数えたい場合

data.reduce((a: (person & {count: number})[], b) => {
    const duplicated = a.find(e => e.name == b.name && e.age == b.age)
    duplicated ? duplicated.count += 1 : a.push({...b, count: 1})
    return a
}, [])

/*
[
  {name: "aaa", age: 18, count: 1},
  {name: "bbb", age: 20, count: 2},
  {name: "bbb", age: 21, count: 1},
  {name: "ccc", age: 21, count: 1},
]
*/

name が重複する連続するオブジェクトを取り除きつつ数えたい場合

data.reduce((a: (person & {count: number})[], b) => {
    const last = a[a.length - 1]
    last && b.name === last.name ? last.count += 1 : a.push({...b, count: 1})
    return a
}, [])

/*
[
  {name: "aaa", age: 18, count: 1},
  {name: "bbb", age: 20, count: 2},
  {name: "ccc", age: 21, count: 1},
  {name: "bbb", age: 20, count: 1},
]
*/

他の書き方もあればフィードバックしてください。

そういえば、a(person & {count: number}[])型を与えない場合、anever[]型と推論されました。処理の内容から推論できると思ったのですが、どういうわけなんでしょう。

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?