js 一个数组中的value,是另外一个数组的key,并且取出key的值?

  var arr1 = [{
    id: 1,
    color: 'white'
  }, {
    id: 2,
    color: 'red'
  }]
  var arr2 = [{
    id: 1,
    white: 'aa'
  }, {
    id: 2,
    red: 'bb'
  }]

根据第一个数组中的value,得出我想要最终结果是['aa','bb'],求大神指导

阅读 2.7k
3 个回答
arr1.map(({color}) => arr2.find(o => o.hasOwnProperty(color))?.[color]);

先把第二个数组预处理成对象,减少循环次数(降低复杂度),然后再遍历第一个数组去匹配:

这里有个问题需要做决定,如果第二个数组里,有两个元素都有 { white: '??' } 这个值时,拿先匹配的还是后匹配的?如果拿先匹配的,则倒序预处理第二个数组,否则正序。
// 如果后匹配优先级高,则不需要先倒序第二个数组
const map = arr2.reverse().reduce(Object.assign, {})

// 精准一些的话 Object.assign 可以准确传参
const map = arr2.reverse().reduce((prev, current) => Object.assign(prev, current), {})

arr1.map(({ color }) => map[color]) // ['aa', 'bb']

分两步考虑,

第一步,在 arr2 中按 color 查找值

function findByColor(color) {
    return arr2.find(item => color in item)?.[color];
}

第二步,对 arr1 中的元素进行映射,把对应的值找出来

const result = arr1.map(({ color }) => findByColor(color));

两步合并在一起就是

const result = arr1.map(({ color }) => arr2.find(it => color in it)?.[color]);

这里 arr2 的数据量不大,所以使用 find 并不会有太大的效率影响,如果量大,可以先创建映射表

const findByColor = ((list) => {
    const map = Object.fromEntries(
        list.flatMap(
            it => Object.entries(it).filter(({ key }) => key !== "id")
        )
    );
    return color => map[color];
})(arr2);

注意到,其实可以直接合并 arr2 的所有对象来生成 map,所以上面的代码还可以改改,直接用 Object.assign() 来合并,最后删除掉 id 这个属性就好。

const findByColor = ((list) => {
    const map = Object.assign({}, ...list);
    return color => map[color];
})(arr2);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题