json 在 JavaScript 中只向数组添加唯一对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17350363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add only unique objects to an array in JavaScript
提问by S16
Let's say I start with this:
假设我从这个开始:
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"
}
]
I use this to prepopulate a form.
Users can editentries or addnew ones. I need to prevent them from adding duplicates.
我用它来预填充表单。
用户可以编辑条目或添加新条目。我需要防止他们添加重复项。
The issue is that the structure of the form that I am serializing and the order these values are returned from the database are not the same, so there is a chance that I will insert an item into this array with the following format:
问题是我正在序列化的表单的结构和这些值从数据库返回的顺序不同,所以我有可能将一个项目插入到这个数组中,格式如下:
{
"country": "US",
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"zip": "22201",
"city": "Arlington",
"state": "VA"
}
Which is the same as the first entry, just ordered differently.
这与第一个条目相同,只是顺序不同。
I am loading underscorejs, so if there's a way to handle it with that library that would be great. I'm also using jQueryif that helps.
我正在加载underscorejs,所以如果有一种方法可以用那个库来处理它,那就太好了。如果有帮助,我也在使用jQuery。
At this point I'm not sure how to proceed.
在这一点上,我不确定如何继续。
回答by Bergi
The Underscore findWherefunctiondoes exactly what you need - it's not an indexOfsearch by object identity, but searches objects whose properties have the same values as the input.
该下划线findWhere功能不正是你所需要的-这不是一个indexOf按对象身份搜索,但搜索的对象,其属性具有与输入相同的值。
if (_.findWhere(shippingAddresses, toBeInserted) == null) {
shippingAddresses.push(toBeInserted);
}
回答by vsync
Basic example using lodashunionmethod:
使用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>
While this doesn't directly answers the question, it does answers the broader question of how to add unique values to an Array, and like myself, others might stumble upon this page from google.
虽然这并没有直接回答问题,但它确实回答了如何向数组添加唯一值的更广泛问题,并且像我一样,其他人可能会从谷歌偶然发现这个页面。
回答by Ashley Raiteri
based on this answer to: "js-remove-an-array-element-by-index-in-javascript"
基于这个答案:“js-remove-an-array-element-by-index-in-javascript”
https://stackoverflow.com/a/7142909/886092
https://stackoverflow.com/a/7142909/886092
I'm using the following idiom that is concise and does not require underscore.js or any other framework.
我正在使用以下简洁的习语,不需要 underscore.js 或任何其他框架。
Here is an example for recording selected and deselected rows for DataTables jquery plugin. I keep an array of currently selected ids, and I don't want to end up with duplicates in the array:
这是一个记录 DataTables jquery 插件的选定和取消选定行的示例。我保留了一组当前选定的 id,我不想在数组中出现重复项:
in 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)
More generally it would
更普遍的是
position = myArray.indexOf(myval)
unless ~position
myArray.push myVal
or in JS
或在 JS
var position;
position = myArray.indexOf(myval);
if (!~position) {
myArray.push(myVal);
}
回答by Matthew Graves
EDIT, this will work with your example of unsorted properties:
编辑,这将适用于您的未排序属性示例:
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});
and we could do this with a one-liner but it would be super ugly:
我们可以用单线来做到这一点,但它会非常难看:
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});
回答by Chickenrice
If you want to check the user input object you could try this function:
如果你想检查用户输入对象,你可以试试这个功能:
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");
}
});
}
And try to invoke this check function in different parameter (uniqueInput and duplicatedInput) I think it could check the duplication input in your shipping addresses.
并尝试在不同的参数(uniqueInput 和duplicatedInput)中调用此检查函数,我认为它可以检查您的送货地址中的重复输入。
checkDuplication(uniqueInput,shippingAddresses);
checkDuplication(duplicatedInput,shippingAddresses);
I make a jsfiddle. You could try it. Hope this is helpful for you.
我做了一个jsfiddle。你可以试试。希望这对你有帮助。
回答by Paul Sturm
Basic example using Set()from ECMAScript 2015 (no library required)
使用Set()ECMAScript 2015 的基本示例(不需要库)
The Setobject lets you store unique values of any type (whether primitive values or object references). If an iterable object is passed, all of its elements will be added to the new Set. Here I'll just add one value:
该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]
回答by Rohit Nishad
I think you need this,
我想你需要这个
NOTE:No library is required.
注意:不需要库。
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)
}
}

