在JavaScript中仅向数组添加唯一对象

时间:2013-06-27 18:13:02

标签: javascript arrays json sorting underscore.js

让我说我从这开始:

var shippingAddresses =      [{
                                "firstname": "Kevin",
                                "lastname": "Borders",
                                "address1": "2201 N Pershing Dr",
                                "address2": "Apt 417",
                                "city": "Arlington",
                                "state": "VA",
                                "zip": "22201",
                                "country": "US"
                            }, {
                                "firstname": "Dan",
                                "lastname": "Hess",
                                "address1": "304 Riversedge Dr",
                                "address2": "",
                                "city": "Saline",
                                "state": "MI",
                                "zip": "48176",
                                "country": "US"
                            }];

我用它预填充表格。用户可以编辑条目或添加新条目。我需要阻止它们添加重复项。

问题是我序列化的表单结构以及从数据库返回这些值的顺序是不一样的,所以我有可能使用以下格式将项目插入到此数组中:

                            {
                                "country": "US",
                                "firstname": "Kevin",
                                "lastname": "Borders",
                                "address1": "2201 N Pershing Dr",
                                "address2": "Apt 417",
                                "zip": "22201",                                    
                                "city": "Arlington",
                                "state": "VA"
                            }

与第一个条目相同,只是采用不同的方式。

我正在加载underscorejs,所以如果有办法用这个库处理它会很棒。如果有帮助我也会使用jQuery。

此时我不知道该怎么办。

7 个答案:

答案 0 :(得分:28)

Underscore findWhere function完全符合您的需要 - 它不是按对象标识进行的indexOf搜索,而是搜索其属性与输入值相同的对象。

if (_.findWhere(shippingAddresses, toBeInserted) == null) {
    shippingAddresses.push(toBeInserted);
}

答案 1 :(得分:15)

使用 lodash End / return方法的基本示例:



var a = [1,2,3];

// try to add "1" and "4" to the above Array
a = _.union(a, [1, 4]);

console.log(a);

<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
&#13;
&#13;
&#13;

虽然这并没有直接回答这个问题,但它确实回答了如何向数组添加唯一值这一更广泛的问题,而像我一样,其他人可能会从谷歌这个页面上绊倒。

答案 2 :(得分:3)

基于以下答案:“js-remove-an-array-element-by-index-in-javascript”

https://stackoverflow.com/a/7142909/886092

我正在使用以下简洁的习惯用法,不需要使用underscore.js或任何其他框架。

以下是记录DataTables jquery插件的选定行和取消选择行的示例。 我保留了一组当前选中的ID,我不希望最终在数组中出现重复:

coffeescript中的

  fnRowSelected: (nodes) ->
    position = $selected.indexOf(nodes[0].id)
    unless ~position
      $selected.push nodes[0].id
    return
  fnRowDeselected: (nodes) ->
    position = $selected.indexOf(nodes[0].id)
    if ~position
      $selected.splice(position, 1)

更普遍的是

position = myArray.indexOf(myval)
unless ~position
  myArray.push myVal

或JS

var position;

position = myArray.indexOf(myval);

if (!~position) {
  myArray.push(myVal);
}

答案 3 :(得分:1)

编辑,这将适用于未分类属性的示例:

var normalized_array = _.map(shippingAddresses, function(a){ 
      var o = {}; 
      _.each(Object.keys(shippingAddresses[0]), function(x){o[x] = a[x]});
      return o;
})
var stringy_array = _.map(normalized_array, JSON.stringify);
shippingAddresses = _.map(_.uniq(stringy_array), JSON.parse});

我们可以用一个班轮来做这件事,但这会非常难看:

shippingAddresses_uniq = _.map(_.uniq(_.map(_.map(shippingAddresses, function(a){ var o = {}; _.each(Object.keys(shippingAddresses[0]), function(x){o[x] = a[x]}); return o; }), JSON.stringify)), JSON.parse});

答案 4 :(得分:1)

如果要检查用户输入对象,可以尝试此功能:

var uniqueInput = {
                       "country": "UK",
                       "firstname": "Calvin",
                       "lastname": "Borders",
                       "address1": "2201 N Pershing Dr",
                       "address2": "Apt 417",
                       "city": "Arlington",
                       "state": "VA",
                       "zip": "22201"

                        };

var duplicatedInput = {
                       "country": "US",
                       "firstname": "Kevin",
                       "lastname": "Borders",
                       "address1": "2201 N Pershing Dr",
                       "address2": "Apt 417",
                       "city": "Arlington",
                       "state": "VA",
                       "zip": "22201"

                        };

var shippingAddresses = [{
                       "firstname": "Kevin",
                       "lastname": "Borders",
                       "address1": "2201 N Pershing Dr",
                       "address2": "Apt 417",
                       "city": "Arlington",
                       "state": "VA",
                       "zip": "22201",
                       "country": "US"
                        }, {
                            "firstname": "Dan",
                            "lastname": "Hess",
                            "address1": "304 Riversedge Dr",
                            "address2": "",
                            "city": "Saline",
                            "state": "MI",
                            "zip": "48176",
                            "country": "US"
                        }];

function checkDuplication(checkTarget,source){
    _.each(source,function(obj){
        if(_.isEqual(checkTarget,obj)){ 
            alert("duplicated");
        }
    });
}

尝试在不同的参数中调用此检查函数(uniqueInput和duplicatedInput) 我认为它可以检查您的送货地址中的复制输入。

checkDuplication(uniqueInput,shippingAddresses);
checkDuplication(duplicatedInput,shippingAddresses);

我制作了jsfiddle。你可以尝试一下。 希望这对你有所帮助。

答案 5 :(得分:1)

使用ECMAScript 2015中的logIn的基本示例(不需要库)

Set()对象使您可以存储任何类型的唯一值(原始值或对象引用)。如果传递了可迭代对象,则其所有元素将添加到新的Set中。在这里,我只添加一个值:

Set

答案 6 :(得分:0)

我认为您需要这个

注意: 不需要库。

import SwiftUI

struct PisteRow: View {
    var pista: Structure

    var body: some View {
        HStack {
            padding()
            pista.image
                .resizable()
                .frame(width: 50, height: 50)
                .clipShape(Circle())
            Text(pista.name)
            Spacer()
        }
    }
}

struct PisteRow_Previews: PreviewProvider {
    static var previews: some View {
        PisteRow(pista: pisteData[0])
            .previewLayout(.fixed(width: 300, height: 70))
    }
}