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

在JavaScript中仅向数组添加唯一对象,javascript,arrays,json,sorting,underscore.js,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", "count

假设我从这个开始:

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"
}
与第一个条目相同,只是顺序不同

我正在加载下划线,所以如果有办法用这个库处理它,那就太好了。如果有帮助的话,我也在使用jQuery


此时,我不确定如何继续。

编辑,这将适用于未排序属性的示例:

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});

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

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和DuplicateInput)中调用此检查函数 我想它可以检查您的发货地址中的重复输入

checkDuplication(uniqueInput,shippingAddresses);
checkDuplication(duplicatedInput,shippingAddresses);
我做了一个决定。你可以试试。 希望这对您有所帮助。

的功能正是您所需要的-它不是按对象标识搜索的
索引,而是搜索属性与输入值相同的对象

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

基于以下回答:“js在javascript中通过索引删除数组元素”

我使用的是以下简洁的习惯用法,不需要下划线.js或任何其他框架

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

咖啡脚本

更一般地说是这样

position = myArray.indexOf(myval)
unless ~position
  myArray.push myVal
或者用JS

var position;

position = myArray.indexOf(myval);

if (!~position) {
  myArray.push(myVal);
}
使用lodash方法的基本示例:
var a=[1,2,3];
//尝试将“1”和“4”添加到上述数组中
a=并(a[1,4]);
控制台日志(a)
使用ECMAScript 2015中的
Set()
的基本示例(无需库)
Set
对象允许您存储任何类型的唯一值(无论是基元值还是对象引用)。如果传递了一个iterable对象,那么它的所有元素都将添加到新的
集合
。在这里,我只添加一个值:

//已存在重复的原始数组
常量数=[1,1,1,2,3,100]
//使用Set从数组中删除重复的元素
//并防止新添加的内容导致重复。
//由于新值(100)存在(和数组),因此不会添加它
//还包括重复数据消除)
console.log(Array.from(新集合([…number,100]))
// [1, 2, 3, 100]
//添加新的、不存在的值(101)(并消除阵列重复)
log(Array.from(新的集合([…number,101]))
//[1,2,31001]
我想你需要这个

注意:不需要库

let数组=[{id:1},{id:2},{id:3}];
函数addUniqeObj(数据){
设指数=-1;
for(设i=0,i-1){
数组[索引]=数据;
}否则{
array.push(数据)
}
}

您是否需要使用ux对对象的属性进行排序?我不需要对属性进行排序,不。我特别尝试以一种与属性顺序无关的方式进行排序。您是否真的将序列化的JSON字符串相互比较,或者您为什么认为顺序很重要?向我们展示您用于防止重复的代码我现在不是在防止重复,这就是我发布此问题的原因。好的,我答案的新编辑现在应该适用于可变属性定位的对象。这将适用于重复,即使属性的顺序不同?实际上,如果属性的顺序不同,似乎也不会。等一下,让我来修一下……但它真的很难看。顺便说一句,你应该只使用
\uu.map(…,JSON.parse)
而不是那些不必要的包装。我认为这是最好的方法。特别是考虑到你有下划线。我可以重构我的代码,使其在没有下划线的情况下工作,但这是一种方法。由于比较宽松,此代码的行为正确
=
,但
必须针对
未定义的
空的
进行测试(根据)@physocoder:正是我想要的:-)当然,如果你更喜欢的话,你也可以使用
===undefined
。如果你用JS而不是coffeescript来回答,也许你会获得更多的选票,因为这个问题显然是关于用JS来做的:)这个问题是专门针对
对象的,而不是
整数的。当对<代码> SET执行添加时,它仍然会考虑由于引用而添加的每个新对象都是唯一的。
var position;

position = myArray.indexOf(myval);

if (!~position) {
  myArray.push(myVal);
}
let array = [{ id: 1}, {id: 2}, {id: 3}];

function addUniqeObj(data) {
  let index = -1;

  for(let i = 0, i < array.length; i++) {
    if(array[i].id === data.id) {
      index = i;
    }
  }

  if(index > -1) {
    array[index] = data;
  } else {
    array.push(data)
  }

}