当前位置: 首页 > 知识库问答 >
问题:

javascript - js 比较两个数组,并进行替换掉?

慕容烨
2024-01-11

js 比较两个数组,并进行替换掉?

        let arr = [          {            sk: [              { Name: '数据1', Value: '200' },              { Name: '数据2', Value: '300' },              { Name: '数据3', Value: '400' },            ],          },          {            sk: [              { Name: '数据5', Value: '500' },              { Name: '数据6', Value: '600' },              { Name: '数据7', Value: '700' },            ],          },        ];        let arr2 = {          name: '数据555',          val: [200, 300, 500],        };

需要根据arr2对象里面的val数组里面的值[200, 300, 500]去匹配arr1数组下sk数组里面的Value的值,如果arr1数组下sk数组里面的Value的值和arr2对象里面的val数组里面的值相等就替换Name,把arr2 对象的name 赋值到sk数组里面的Name

期望得到

        let arr = [          {            sk: [              { Name: '数据555', Value: '200' },              { Name: '数据555', Value: '300' },              { Name: '数据3', Value: '400' },            ],          },          {            sk: [              { Name: '数据555', Value: '200' },              { Name: '数据555', Value: '500' },              { Name: '数据7', Value: '700' },            ],          },        ];
        let result = arr.map((item) => {          if (item.sk.length == 0) return;          item.sk.forEach((k) => {            return {              Name: arr2.val.find((t) => t == k.Value)?.name,            };          });          return item;        });

这样写了调试了还没效果。麻烦大佬们帮我看看

共有4个答案

龙承德
2024-01-11

错有点多,注意序号,相同序号是对同一个错误的描述

// ❶ 这里有两层数组,对外层 map 替换掉的是第一层的对象let result = arr.map((item) => {    // ❸ 如果是 map,通常需要返回一个值/对象,    // ❸ 直接 return 相当于 return undefined,    // ❸ 也就是把 map 出来的新数组中对应位置的元素变成了 undefined    if (item.sk.length == 0) return;    // ❷ 对 item.sk 进行遍历处理,想法没错,但是处理错了    // ❷ 需要适当改变 sk 中的元素,既然是改变,应该用 map,    // ❷ 并且将 map 出来的新对象组成的数组赋值给 sk 替换掉它    item.sk.forEach((k) => {        return {            // ❹ 新生成的对象只有 Name,没有 Value,至少应该补一个 Value 属性进去            // ❺ arr2.val.find 找到的结果是 val 中的值,比如 200,它是没有 name 属性的,            // ❺ 所以永远是 undefined            Name: arr2.val.find((t) => t == k.Value)?.name,        };    });    // ❶ 但是很显然,没有替换为新对象    // ❶ 所以第一层是不需要 map 的,只需要 forEach 就好    return item;});

修改后的

// 因为原数据是字符串类型,所以将需要检索的数组值也改成字符串类型,// 方便后面用 includes 来判断是否存在const values = arr2.val.map(v => `${v}`);// 直接遍历,在 arr 中修改对应的对象属性arr.forEach(item => {    if (!item.sk.length) { return; }    // 注意 map 不会改变原数组,需要对 sk 重新赋值    // 箭头函数返回一个对象的时候,可以用 ({...}),不需要 return    item.sk = item.sk.map(k => ({        // 判断如果值在事先准备的 values 中,用 arr2.name        // 否则还是用 k.Name        Name: values.includes(k.Value) ? arr2.name : k.Name,        // 别忘了还有 Value        Value: k.Value    }));});

因为是直接改原数据,所以里面的 map 其实也是可以用 forEach 遍历来处理的,直接替换掉符合条件的 Name 就行

const values = arr2.val.map(v => `${v}`);arr.forEach(item => {    if (!item.sk.length) { return; }    item.sk.forEach(k => {        // 遍历并对符合条件的数据替换掉 Name        if (values.includes(k.Value)) {            k.Name = arr2.name;        }    });});
容鸿畴
2024-01-11

有2个知识点,

  1. 数组的 map 方法返回一个新数组,map参数中回调函数的返回值作为一个元素被添加为新数组中。
  2. 在 forEach 里面 return 实现的是类似 for 循环里 continue 语句的效果,return 的内容没什么作用。

你的需求要不要改动原数组?
改动原数组:

let arr2 = {  name: '数据555',  val: [200, 300, 500],};function change (arr) {    arr.forEach(item => {        if (item.sk) {            item.sk = item.sk.map(skItem => {                // 注意你提供的值,分别是 number 类型和 string 类型                if (arr2.val.find(arr2Item => arr2Item.toString() === skItem.Value)) {                    skItem.Name = arr2.name                }                return skItem            })        }    })}change(arr);

不改动源数组:

let arr2 = {  name: '数据555',  val: [200, 300, 500],};function change (arr) {    let result = arr.map(item => {        if (item.sk) {            item.sk = item.sk.map(skItem => {                // 注意你提供的值,分别是 number 类型和 string 类型                if (arr2.val.find(arr2Item => arr2Item.toString() === skItem.Value)) {                    skItem.Name = arr2.name                }                return skItem            })        }        return item;    })    return result;}change(arr);
张成济
2024-01-11
let result = arr.map((item) => {    if (item.sk.length === 0) return;    item.sk.forEach((k) => {        if (arr2.val.includes(Number(k.Value))) {            k.Name = arr2.name        }    });    return item;});

image.png

蔡晨
2024-01-11

你的代码中存在一些问题,这可能是导致它没有按预期工作的原因。这里我提供了一种解决方案,使用了 Array.prototype.map()Array.prototype.find() 方法:

let arr = [  {    sk: [      { Name: '数据1', Value: '200' },      { Name: '数据2', Value: '300' },      { Name: '数据3', Value: '400' },    ],  },  {    sk: [      { Name: '数据5', Value: '500' },      { Name: '数据6', Value: '600' },      { Name: '数据7', Value: '700' },    ],  },];let arr2 = {  name: '数据555',  val: [200, 300, 500],};let result = arr.map((item) => {  return item.sk.map((skItem) => {    let found = arr2.val.find((v) => v == skItem.Value);    if (found) {      return { ...skItem, Name: arr2.name };    } else {      return skItem;    }  });});

在这个代码中,我们首先遍历数组 arr 中的每个元素,然后对每个元素中的 sk 数组进行遍历。然后,我们使用 find() 方法在 arr2.val 数组中查找与当前 skItem.Value 相等的值。如果找到了匹配的值,我们将该 skItemarr2.name 合并并返回;否则,我们直接返回当前的 skItem

 类似资料:
  • 我有一个简单的javascript问题,我真的需要一些帮助!我正在尝试弄清楚如何在数组之间比较元素,以及在下一个循环中再次比较较大的元素。假设我们有数组A和数组B。 我的问题是,在比较索引处的元素之后,我希望在下一个循环周期中比较较大的元素。 如果A=[5,7,4],B=[2,8,5] 在第一个循环中,5与2进行比较,2较小,因此会发生一些事情。在下一个循环周期中,我希望5与8进行比较,而对于现在

  • 问题内容: 如果它具有另一个数组的元素,是否还有其他更好的方法可以从一个数组中删除重复项呢,它工作得很好。 问题答案: 或者,随着ES6的推出:

  • 问题内容: 我有这个间隔,当前每5秒执行一次ajax请求。我对声明有疑问。我的代码总是输入它,并且两个json值完全相同,为什么它认为它们不同? 编辑 这是控制台输出(虚线是分隔请求,它不在实际输出中) 问题答案: 不能保证以相同的方式序列化JSON对象,也不能保证属性以相同的顺序进行序列化,使用并不是测试对象相等性的好方法。 一个更好的例子是这样的函数(前一段时间在互联网上找到,希望我能感谢原始

  • 我怎样才能比较这两个数组,以一种我想返回另一个数组的方式,它包含B中的所有a的值? 返回数组: 来自答案的C#代码:

  • 问题内容: 我想比较两个JavaScript对象数组,以查看它们是否相同。每个数组中的对象可能不会(并且很可能不会)以相同的顺序排列。每个数组最多只能有10个对象。我以为jQuery可以解决这个问题,但是我在网上找不到很多。 我知道可以使用简单的嵌套解决方案,但是有我不知道的内置函数吗? 谢谢。 问题答案: 有一个简单的方法… 如果以上返回true,则即使元素的顺序不同,两个数组也相同。 注意:仅

  • 本文向大家介绍JavaScript 数组比较,包括了JavaScript 数组比较的使用技巧和注意事项,需要的朋友参考一下 示例 为了进行简单的数组比较,您可以使用JSON stringify并比较输出字符串: 注意:这仅在两个对象都可以JSON序列化并且不包含循环引用的情况下起作用。可能会抛出TypeError: Converting circular structure to JSON 您可以