20

假设我从这个开始:

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 。

在这一点上,我不确定如何进行。

4

7 回答 7

30

Underscore函数完全符合您的需要 - 它不是按对象身份进行搜索findWhereindexOf,而是搜索属性与输入值相同的对象。

if (_.findWhere(shippingAddresses, toBeInserted) == null) {
    shippingAddresses.push(toBeInserted);
}
于 2013-06-27T19:03:15.557 回答
16

使用lodash union方法的基本示例:

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>

虽然这并不能直接回答这个问题,但它确实回答了更广泛的问题,即如何向数组添加唯一值,并且像我自己一样,其他人可能会偶然发现谷歌的这个页面。

于 2016-07-17T22:18:08.127 回答
5

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

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

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

这是记录 DataTables jquery 插件的选定行和取消选定行的示例。我保留了一个当前选定的 id 数组,并且我不想在数组中出现重复项:

在咖啡脚本中

  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);
}
于 2014-02-10T17:06:36.293 回答
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});
于 2013-06-27T18:17:49.603 回答
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。你可以试试。希望这对你有帮助。

于 2013-06-27T18:37:13.120 回答
1

我觉得你需要这个

注意: 不需要库。

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

}
于 2020-04-14T16:08:49.647 回答
-1

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

Set对象允许您存储任何类型的唯一值(无论是原始值还是对象引用)。如果传递了一个可迭代对象,它的所有元素都将被添加到新的Set. 在这里,我将只添加一个值:

// original array with duplicates already present
const numbers = [1, 1, 1, 2, 3, 100]

// Use Set to remove duplicate elements from the array 
// and keep your new addition from causing a duplicate.

// New value (100) is not added since it exists (and array 
// also is de-duped)
console.log(Array.from(new Set([...numbers, 100])))
// [1, 2, 3, 100]

// New, non-existing value (101) is added (and array is de-duped)
console.log(Array.from(new Set([...numbers, 101])))
// [1, 2, 3, 100, 101]

于 2019-02-13T22:32:11.123 回答