如果我有两个像这两个对象的数组
const x = [{id: 1, a: 5}, {id: 2, a:10}, {id: 3, a: 12}];
const y = [{id: 4, a: 0}, {id: 2, a: 0}, {id: 3, a: 0}];
输出应为代表y
的新数组
但是经过一些修改,如果y中的项目具有id
与x中的项目匹配,则a
的值应与x相同,因此输出应为
[{id: 4, a: 0}, {id: 2, a: 10}, {id: 3, a: 12}]
这是我的解决方法
const z = [...y];
z.forEach(el => x.map(ele => el.a = el.id === ele.id ? ele.a : el.a));
这是我在项目中所做的一个简单实现,我关心性能,并且我看到克隆数组z = [...y]
的步骤可能会很昂贵,因此我正在寻找使用返回函数的解决方案新数组map
,filter
,reduce
...,
我尝试嵌套map
和filter
,find
...,但是我以复杂的解决方案作为结尾,那么还有其他解决方案在同时具有更高的性能和简单性吗? / p>
答案 0 :(得分:2)
您可以通过单次迭代从x
从y
创建一个xObj,而不是为x
遍历y
并在(constant lookup O(1) )
上循环,只需检查它是否存在如果是,请在xObj const x = [{id: 1, a: 5}, {id: 2, a:10}, {id: 3, a: 12}];
const y = [{id: 4, a: 0}, {id: 2, a: 0}, {id: 3, a: 0}];
var xObj = {};
x.forEach(function(val){
xObj[val.id] = val.a;
});
const newY = y.reduce(function(o,i){
if(xObj.hasOwnProperty(i.id)){
i.a = xObj[i.id];
}
o.push(i);
return o;
},[]);
console.log(newY);
中进行更新,否则请使用现有值进行更新。
public class ArrayExample {
public static void main(String[] args) {
int a[]= {12,3,-1,4,-2,8,-9,-6,4,78};
int len=a.length;
int i,j,k;
int pcount=0,ncount=0;
int b[]=new int[len];
for(i=0;i<len;i++) // for counting positive & negative nos.
{
if(a[i]>0)
{
pcount++;
}
else
ncount++;
}
//Buffer Array
int pos[]=new int[pcount];
int neg[]=new int[ncount];
// Inserting into resp. arrays
for(i=0,j=0,k=0;i<len;i++)
{
if(a[i]<0 && j<ncount)
{
neg[j]=a[i];
j++;
}
if(a[i]>0 && k<pcount)
{
pos[k]=a[i];
k++;
}
}
System.out.println("Arr "+Arrays.toString(a));
System.out.println("Pos "+Arrays.toString(pos));
System.out.println("Neg "+Arrays.toString(neg));
//Insert into final array
for(i=0,j=0,k=0;i<(len);i++)
{
if(i%2==0 && j<pcount)
{
b[i]=pos[j];
j++;
}
if(i%2!=0 && k<ncount)
{
b[i]=neg[k];
k++;
}
}
//Final no. correction
System.out.println("Final "+Arrays.toString(b));
}
}
答案 1 :(得分:1)
对于这样的问题,您应该关心创建新数组的计算费用少,而关心通过多个数组运行的大O费用 more 多次。您的解决方案和@NitishNarang发布的另一种解决方案似乎都为O(n ^ 2),因为随着数组的增大,求解所需的步骤数呈指数增长。
我个人将只创建一个新的Map()
并逐个检查每个项目,仅当与该ID对应的Map()
的值大于该值时,才将其添加到a
当前存储的一个。除了添加唯一的ID值之外,基本上这是一个稍微复杂的排序工作。
const x = [{id: 1, a: 5}, {id: 2, a:10}, {id: 3, a: 12}];
const y = [{id: 4, a: 0}, {id: 2, a: 0}, {id: 3, a: 0}];
const myMap = new Map();
for (const ea of x) {
if (!myMap.has(ea.id) || ea.a >= myMap.get(ea.id).a) {
myMap.set(ea.id, ea);
}
}
for (const ea of y) {
if (!myMap.has(ea.id) || ea.a >= myMap.get(ea.id).a) {
myMap.set(ea.id, ea);
}
}
const result = [...myMap.values()];
此解决方案为O(n),即线性的,这意味着如果您向数组x
或y
或两者中添加10或100或1000个以上的项目,则只会添加那么多运行解决方案的更多步骤,而不是10 ^ 2或100 ^ 2或1000 ^ 2,因为您必须对照每个数组中的每个其他项目检查每个数组中的每个项目(就像您对原始解决方案所做的那样。)>
编辑:正如@SZenC所指出的,上述解决方案由于将两个数组组合在一起而不太正确。为了仅在项目最初存在于数组y
中时才有选择地匹配项,只需先对y
进行迭代,然后在对x
进行迭代时仅替换值(如果它们已经存在于映射中) :
const x = [{id: 1, a: 5}, {id: 2, a:10}, {id: 3, a: 12}];
const y = [{id: 4, a: 0}, {id: 2, a: 0}, {id: 3, a: 0}];
const myMap = new Map();
for (const ea of y) {
if (!myMap.has(ea.id) || ea.a >= myMap.get(ea.id).a) {
myMap.set(ea.id, ea);
}
}
for (const ea of x) {
if (myMap.has(ea.id) && ea.a >= myMap.get(ea.id).a) {
myMap.set(ea.id, ea);
}
}
const result = [...myMap.values()];
答案 2 :(得分:1)
使用Set
将ids
存储在x
数组中,并在map
数组上使用y
来检查y's
{{1 }}是否存在于id
中。
Set
希望这会有所帮助!
答案 3 :(得分:0)