Javascript 将项添加到数组中或替换它(如果它具有相同的id)
我有这个对象数组Javascript 将项添加到数组中或替换它(如果它具有相同的id),javascript,arrays,object,Javascript,Arrays,Object,我有这个对象数组 var source = [ {id: 1, label: "one"}, {id: 2, label: "two"}, {id: 3, label: "three"} ]; 我需要添加一个项目或替换它,如果它有相同的id var new_sub = {id: 1, label: "new label for one"}; var new_add = {id: 4, label: "four"}; source = myFunc(new_sub); source
var source = [
{id: 1, label: "one"},
{id: 2, label: "two"},
{id: 3, label: "three"}
];
我需要添加一个项目或替换它,如果它有相同的id
var new_sub = {id: 1, label: "new label for one"};
var new_add = {id: 4, label: "four"};
source = myFunc(new_sub);
source = myFunc(new_add);
function myFunc(obj) {
return (source.findIndex(x => x.id === obj.id) === -1) ?
source.concat(obj) : source.map((item) => {
return (item.id === obj.id) ? obj : item;
});
}
这段代码工作得很好,但是有更好的方法吗?
您可以将我的代码检查到此snippit:
var源=[
{id:1,标签:“一”},
{id:2,标签:“2”},
{id:3,标签:“三”}
];
var new_sub={id:1,标签:“一个新标签”};
var new_add={id:4,标签:“四”};
source=myFunc(新的_sub);
source=myFunc(新添加);
函数myFunc(obj){
返回(source.findIndex(x=>x.id==obj.id)=-1)?
source.concat(obj):source.map((项)=>{
返回(item.id==obj.id)?obj:item;
});
}
//印刷品
var html=“”;
source.map((项目)=>{
html+=“”+item.id+”-“+item.label+” ”;
});
$(“#resp”).html(html)代码>
注意:您版本的myFunc
每次调用时都会创建一个新数组。我的版本没有。但是,由于您正在将myFunc
的返回值存储回sources
,我想不需要创建新数组(在我的版本中,由于数组sources
发生变异,您不必执行sources=myFunc(…)
)
旧浏览器支持:(实际上更好)
函数myFunc(obj){
for(var i=0;i }
您正在对数组进行多次传递(一次在findIndex
中,然后一次在concat
或map
中),这是不必要的。只需通过一次即可:
function myFunc(a, obj) {
let found = false;
const result = a.map(e => {
if (!found && e.id === obj.id) {
found = true;
return obj;
} else {
return e;
}
});
if (!found) {
result.push(obj);
}
return result;
}
请注意,我将源数组作为参数传递到函数中,因此它没有副作用
var源=[
{id:1,标签:“一”},
{id:2,标签:“2”},
{id:3,标签:“三”}
];
var new_sub={id:1,标签:“一个新标签”};
var new_add={id:4,标签:“四”};
source=myFunc(source,new_sub);
source=myFunc(source,new_add);
console.log(源代码);
函数myFunc(a,obj){
让发现=错误;
const result=a.map(e=>{
如果(!found&&e.id===obj.id){
发现=真;
返回obj;
}否则{
返回e;
}
});
如果(!找到){
结果:推送(obj);
}
返回结果;
}
如果您经常这样做(插入几千个元素),那么构建一个哈希表(查找数组的时间为O(1)而不是O(n))可能会更好(关于性能):
函数myFunc(o)
{
让我;
如果((i=source[0].indexOf(o.id))<0)
{
源[0]。推送(o.id);源。推送(o)
}
其他的
{
源[1+i]=o
}
//返回JSON.parse(JSON.stringify(source))//带有原语的新数组
返回源//作为引用
}
变量源=[
[4,1,3,2]//这里的诀窍
,{id:4,标签:“四”}
,{id:1,标签:“一”}
,{id:3,标签:“三”}
,{id:2,标签:“两”}
];
var new_sub={id:1,标签:“一个新标签”};
var new_add={id:6,标签:“六个新标签”};
source=myFunc(新的_sub);
console.log(“//=>新子项后的源”,源);
source=myFunc(新添加);
console.log(“//=>新添加后的源”,source)
在我看来,[obj.id]应该可以正常工作?@Camile它应该是[obj.id-1]
,这不是一种可靠的方法。每次调用函数时都需要创建一个新数组吗?请注意:=>
函数不受IE
支持,为性能优化的代码很少更可读。通常,在将这段代码确定为系统中的性能瓶颈之前,您不会优化性能并牺牲可读性。是吗?你正在修改输入数组。OP的代码生成一个新数组。这是一个重要的语义差异。@T.J.Crowder你说得对。但我刚刚注意到他正在做sources=myFunc(…)
,因此不需要创建新数组。我也加了一张便条。@Red那是OP的选择。他已经在使用箭头函数和findIndex了。是的,我知道。请注意,对于希望在其他情况下使用此功能的用户:)@Red实际上,较旧的浏览器版本看起来比其他版本好得多:)
function myFunc(a, obj) {
let found = false;
const result = a.map(e => {
if (!found && e.id === obj.id) {
found = true;
return obj;
} else {
return e;
}
});
if (!found) {
result.push(obj);
}
return result;
}
var source = [
{id: 1, label: "one"},
{id: 2, label: "two"},
{id: 3, label: "three"}
];
var hash = new Map(source.map((el,i)=>[el.id,i]));
function substitute(elem){
var i = hash.get(elem.id);
if(i !== undefined){
return source[i] = elem;
}
hash.set(elem.id,source.push(elem));
}