1

このオブジェクトの配列(重複するオブジェクトがいくつかある)をどのように回転させることができますか?

items =
  [
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Silver' },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Yellow' },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Blue'   },
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Black'  },
    { TYPEID: 1248350, NAME: 'Staples',    COLOR: 'Black'  },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Blue'   },
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Silver' },
    { TYPEID: 150927,  NAME: 'Fasteners',  COLOR: 'Silver' }
  ]

これに:

items =
  [
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Silver' },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Yellow' },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Blue'   },
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Black'  },
    { TYPEID: 1248350, NAME: 'Staples',    COLOR: 'Black'  },
    { TYPEID: 150927,  NAME: 'Fasteners',  COLOR: 'Silver' }
  ]

... 2つの重複するオブジェクト(銀のステープルと青の鉛筆)を除外することによって?

これを行う簡単な方法があるはずですが、私はまだ簡単な解決策を見つけていません。

これを行うjavascript/jqueryコードを見たことがありますが、それらをcoffeescriptに変換するのは得意ではありません。

アップデート:

多くの場合、非常によく似たプロパティを持つさまざまなオブジェクトがあります。

実際のアプリケーションでは、各オブジェクトには25のプロパティの可能性があります。

これらの各プロパティが等しい場合にのみ、オブジェクトを削除したいと思います。

更新2

これは私のために働くことになったコードです-(rjzに感謝します)

unique = (objAry, callback) ->
  results = []

  valMatch = (seen, obj) ->
    for other in seen
      match = true
      for key, val of obj
        match = false unless other[key] == val
      return true if match
    false

  objAry.forEach (item) ->
    unless valMatch(results, item)
      results.push(item)
  callback null, results

そして、これは私がそれを呼ぶ方法です:

unique items, (err, items) ->
  console.log items
4

4 に答える 4

2

同等性をどの程度深くチェックしたいかにもよりますが、おそらくUSERIDフィールドの一意性を想定して、次のようなことを行うことができます。

ids = []    # Contains list of "seen" IDs
result = [] # Contains list of unique users

users.forEach (u) -> 
  if result.indexOf(u.USERID) == -1
    result.push(u)
    ids.push(u.USERID)

より詳細なマッチングを行う必要があり、使用可能な主キーがない場合(より大きな問題の兆候である可能性があります)、同等性のより高度なテストを作成できます。

valMatch = (seen, obj) ->
  for other in seen
    match = true
    for key, val of obj
      match = false unless other[key] == val
    return true if match
  false

result = []
seen = []

data.forEach (datum) -> 
  unless valMatch(result, datum)
    result.push(datum)
    seen.push(datum)
于 2012-12-07T17:53:42.843 に答える
0

私はunderscore.jsを使用して、このようなことを試みます

result = item[0] for item in _.groupBy(users, (user) => user.USERID)

それはあなたをテストしていません;-)明らかにこれは私たちがUSERIDをチェックするだけであることを前提としています

USERIDだけをチェックできない場合は、もちろんすべてのオブジェクトをjson-stringsに変換してから、jsonstringsを比較することができます。

result = item[0] for item in _.groupBy(users, (user) => user.toJSON())

明らかにこれは、すべてのブラウザとエンジンがオブジェクトとそのスロットを作成/割り当ての順序でシリアル化するという事実に依存する汚いハックです。

したがって、いずれにせよ、rjzのソリューションは確かに優れていますが、これもおそらく機能します。

于 2012-12-07T19:50:18.293 に答える
0

その古い質問-しかし、オールディーズは...

配列内のオブジェクトを結合できます:(すべての値を配列に取得し、それを文字列に結合します)

join_object=(o)->
    ["#{attr}:#{value}" for attr, value of o].join() 

これにより、各objに対してそのような出力が生成されます。

    TYPEID:150927,NAME:Staples,COLOR:Silver     

そして、配列を「一意」にするCoffeeの方法を変更して深くユニークにしましょう。

Array::unique_deep = ->
    output = {}
    output[join_object(@[key])] = @[key] for key in [0...@length]
    value for key, value of output      

短くして保存します。

結果:

Array::unique_deep = ->
    join_object=(o)->
        ["#{attr}:#{value}" for attr, value of o].join()
    output = {}
    output[join_object @[key]] = @[key] for key in [0...@length]
    value for foo_key, value of output                          
于 2019-07-27T03:31:25.103 に答える
-2
Array::uniq = ->
    unique=(v, k, self) ->
        self.indexOf(v)==k
    @.filter(unique)

# console.log([1,2,3,3,4,4,5].uniq())
于 2018-02-11T06:59:36.097 に答える