如何将一个对象数组的一个属性的值分配给另一个对象数组的同名属性? - Javascript

Posted

技术标签:

【中文标题】如何将一个对象数组的一个属性的值分配给另一个对象数组的同名属性? - Javascript【英文标题】:How to assign the value of one attribute of one array of object to the similarly named attribute of another array of object? - Javascript 【发布时间】:2019-07-16 08:59:53 【问题描述】:

这是我的代码

我有 2 个对象数组 - arr1 和 arr2

  var arr1 = [
        id: 1,
        city: 'London',
        'checked': false
        ,
        
        id: 2,
        city: 'NYC',
        'checked': false
        ,
        
        id: 3,
        city: 'Paris',
        'checked': false
        ,
        
        id: 4,
        city: 'Madrid',
        'checked': false
        ];


 var arr2 = [
        id: 1,
        city: 'Madrid',
        'checked': true
        ,
        
        id: 2,
        city: 'Paris',
        'checked': false
        ,
        
        id: 3,
        city: 'NYC',
        'checked': true
        ,
        
        id: 4,
        city: 'London',
        'checked': false
        ];

使用这两个对象数组,我想创建一个 arr3 变量/对象数组(arr3 将保留 arr1 的顺序 - 首先是伦敦,然后是纽约,第三个是巴黎,最后是马德里。我只想检查arr2 对象并将该字段(已检查的属性)值放入 arr1 并创建 arr3。不应更改顺序,仅 arr1 的已检查将从 arr2 的已检查中获取其值。

  var arr3 = [
        id: 1,
        city: 'London',
        'checked': false
        ,
        
        id: 2,
        city: 'NYC',
        'checked': true
        ,
        
        id: 3,
        city: 'Paris',
        'checked': false
        ,
        
        id: 4,
        city: 'Madrid',
        'checked': true
        ];

我还有一个不使用arr3的选项,那么我可以直接在arr1中进行更改。这也是另一种方式。任何技术都适合我。

已更新 - arr3 中 id 属性的顺序应与 arr1 中相同

【问题讨论】:

【参考方案1】:

使用mapforEach

var arr1 = [
    city: 'London',
    'checked': false,
    id: 1
  ,
  
    city: 'NYC',
    'checked': false,
    id: 2
  ,
  
    city: 'Paris',
    'checked': false,
    id: 3
  ,
  
    city: 'Madrid',
    'checked': false,
    id: 4
  
];


var arr2 = [
    city: 'Madrid',
    'checked': true
  ,
  
    city: 'Paris',
    'checked': false
  ,
  
    city: 'NYC',
    'checked': true
  ,
  
    city: 'London',
    'checked': false
  
];
var arr3 = arr1.map(e => 
  arr2.forEach(x => x.city == e.city ? e.checked = x.checked : false)
  return e;
)
console.log(arr3)

【讨论】:

这个三元运算符无用且令人困惑。【参考方案2】:

(更新)步骤:

    遍历arr1。 从两个数组中获取城市属性匹配的arr2 中的对象。 根据来自arr2的匹配对象更新arr1中的checked属性。

var arr1 = [
    id: 1,
    city: 'London',
    'checked': false
  ,
  
    id: 2,
    city: 'NYC',
    'checked': false
  ,
  
    id: 3,
    city: 'Paris',
    'checked': false
  ,
  
    id: 4,
    city: 'Madrid',
    'checked': false
  
];


var arr2 = [
    id: 1,
    city: 'Madrid',
    'checked': true
  ,
  
    id: 2,
    city: 'Paris',
    'checked': false
  ,
  
    id: 3,
    city: 'NYC',
    'checked': true
  ,
  
    id: 4,
    city: 'London',
    'checked': false
  
];

arr1.forEach(a1 => 
  a1.checked = arr2.filter(a2 => a2.city === a1.city)[0].checked
)
console.log(arr1)

【讨论】:

【参考方案3】:

1.遍历第一个数组

2.遍历第二个数组

3.当 arr1 所在城市 == arr 2 所在城市

    在 arr1 中保存检查的 arr2

var arr1 = [
    id: 1,
    city: 'London',
    checked: false
  ,
  
    id: 2,
    city: 'NYC',
    checked: false
  ,
  
    id: 3,
    city: 'Paris',
    checked: false
  ,
  
    id: 4,
    city: 'Madrid',
    checked: false
  
];


var arr2 = [
    id: 1,
    city: 'Madrid',
    checked: true
  ,
  
    id: 2,
    city: 'Paris',
    checked: false
  ,
  
    id: 3,
    city: 'NYC',
    checked: true
  ,
  
    id: 4,
    city: 'London',
    checked: false
  
];

arr1.forEach(function(entry1) 
  arr2.forEach(function(entry2) 
    if (entry1.city == entry2.city) 
      entry1.checked = entry2.checked;
    

  )
);
console.log(arr1);

【讨论】:

如果我在 arr1 和 arr2 中都有一个从 1 到 4 的升序 id 属性会发生什么。假设在 arr1 中,伦敦的 id 为 1,而在 arr2 中,马德里的 ID 为 1。在 arr3 中,我想保留 id 的顺序,如 arr1 @Scooby 我的示例根据数组 2 的检查修改数组 1 我已经修改了问题,添加了另一个名为 id 的字段,请检查 @Scooby ass 你说使用数组 3 是一个选项,所以 arr1 的 id 将保持不变。检查更新的解决方案。【参考方案4】:

您可以将Array.prototype.map() 与Array.prototype.find() 结合使用。使用arr1.map(...),您可以维护数组一的顺序,使用arr2.find(...),您将获得arr2 中的checked 属性值。

const arr1 = [id: 1,city: 'London','checked': false,id: 2,city: 'NYC','checked': false,id: 3,city: 'Paris','checked': false,id: 4,city: 'Madrid','checked': false];
const arr2 = [id: 1,city: 'Madrid','checked': true,id: 2,city: 'Paris','checked': false,id: 3,city: 'NYC','checked': true,id: 4,city: 'London','checked': false];
const arr3 = arr1.map(c1 => (
  id: c1.id,
  city: c1.city,
  checked: arr2.find(c2 => c1.city === c2.city).checked
));

console.log(arr3);
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

【参考方案5】:

解释

通过这种方法,它使用了更多的现代方法,使用了诸如 mapfind 之类的函数,而且我个人认为这种实现非常简单。

如果您不熟悉“箭头函数”语法,可以在网上找到大量文档,例如 this。但正如您所见,这种方法的美妙之处在于它干净、简洁且简单。

这个实现有点类似于@holydragon 提供的答案,但是当你使用forEach 函数时,你允许出现副作用,至少在这个实现中,通过使用map,这应该可以减少代码中出现副作用的机会。

此外,我还使用了destructuring assignment,以进一步减少此 sn-p 中出现副作用的机会。

更新

我使用destructuring assignment 实现了我的解决方案,并不是因为它是“现代”或类似的愚蠢。这是因为在不创建对象副本的情况下,当修改 arr3 中对象的 checked 属性时,arr1 中的对象中的 checked 属性也会更新。

这是一个副作用示例,如果您想深入研究函数式编程、相关概念,特别是使用 javascript 进行函数式编程,我强烈建议您阅读一些 Eric's 内容。就我个人而言,我是 Eric 发布的内容的粉丝,当我尝试将函数式编程概念应用于 JavaScript 时,我发现他的内容很有用。

var arr1 = [id:1,city:"London",checked:!1,id:2,city:"NYC",checked:!1,id:3,city:"Paris",checked:!1,id:4,city:"Madrid",checked:!1];
var arr2 = [id:1,city:"Madrid",checked:!0,id:2,city:"Paris",checked:!1,id:3,city:"NYC",checked:!0,id:4,city:"London",checked:!1];


var arr3 = arr1.map((...o) => 
  o.checked = arr2.find(x => x.city === o.city).checked;
  return o;
);
console.log(arr3);

// If you want a one line solution... 
var arr4 = arr1.map((...o) => Object.assign(o, checked : arr2.find(x => x.city === o.city).checked));
console.log(arr4);

【讨论】:

【参考方案6】:

您可以使用Map 并合并相同的城市。

var array1 = [ city: 'London', checked: false ,  city: 'NYC', checked: false ,  city: 'Paris', checked: false ,  city: 'Madrid', checked: false ],
    array2 = [ city: 'Madrid', checked: true ,  city: 'Paris', checked: false ,  city: 'NYC', checked: true ,  city: 'London', checked: false ],
    result = Array.from([...array1, ...array2]
        .reduce((m, o) => m.set(o.city, o), new Map)
        .values()
    );

console.log(result)
.as-console-wrapper  max-height: 100% !important; top: 0; 

如果需要,您可以将只需要的属性分配给地图。

var array1 = [ id: 1, city: 'London', checked: false ,  id: 2, city: 'NYC', checked: false ,  id: 3, city: 'Paris', checked: false ,  id: 4, city: 'Madrid', checked: false ],
    array2 = [ id: 1, city: 'Madrid', checked: true ,  id: 2, city: 'Paris', checked: false ,  id: 3, city: 'NYC', checked: true ,  id: 4, city: 'London', checked: false ],
    result = Array.from([...array1, ...array2]
        .reduce((m, o) => m.set(
            o.city,
            Object.assign(m.get(o.city) || o,  checked: o.checked )
        ), new Map)
        .values()
    );

console.log(result)
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

我喜欢这个答案,因为它与包括我自己在内的大多数其他答案不同,我不会想到这一点。我唯一的问题是,这会比我提供的解决方案更好/更差吗? :) 我已经修改了问题,它现在有一个 id 属性。你能检查一下修改后的问题吗【参考方案7】:

创建一个对象,键值对作为城市名称,并从数组 2 中检查值。

var array2Obj = ;
for (var i = 0; i < arr2.length; i++) 
    array2Obj[arr2[i].city] = arr2[i].checked;

现在循环数组 1 并将对象的城市值(即数组 2 的检查值)分配给数组 1 的检查值。

for (var i = 0; i < arr1.length; i++) 
    arr1[i].checked = array2Obj[arr1[i].city];

【讨论】:

以上是关于如何将一个对象数组的一个属性的值分配给另一个对象数组的同名属性? - Javascript的主要内容,如果未能解决你的问题,请参考以下文章

Javascript 2对象数组,从一个对象数组中获取一个值并将其分配给另一个对象数组

java技术:怎样将ArrayList的值赋值给一个二维数组啊?

创建数组的随机切片以分配给另一个对象数组

将一个数组中的值分配给另一个数组而不循环

如何一次循环遍历 2 个数组并将数组中的颜色分配给另一个数组的每个值

DELPHI如何获取并赋值给一个对象的方法