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

问题描述 投票:0回答:7

假设我从这个开始:

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

此时,我不知道如何继续。

javascript arrays json sorting underscore.js
7个回答
31
投票

下划线

findWhere
函数完全满足您的需要 - 它不是按对象标识进行
indexOf
搜索,而是搜索属性与输入具有相同值的对象。

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

18
投票

使用 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>

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


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

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 和 duplicdInput)中调用此检查函数 我认为它可以检查您的送货地址中的重复输入。

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

我做了一个jsfiddle。你可以尝试一下。 希望这对您有帮助。


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

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

}

-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]

© www.soinside.com 2019 - 2024. All rights reserved.