为了账号安全,请及时绑定邮箱和手机立即绑定

合并 2 个数组,同时忽略空字段

合并 2 个数组,同时忽略空字段

扬帆大鱼 2022-09-02 16:10:40
我试图将数组2合并到数组1中,以便空字段保持像数组1一样,并且具有值的字段在数组1处从数组2被覆盖。但只有空字段,如果它是空的,则应将其视为数字并覆盖字段。请看这两条评论,以便更好地理解我的意思。我尝试过:const array1 = [[2], [], [3,5], [], [1]]const array2 = [[], [], [4], [], [null]]Array.prototype.splice.apply(array1, [0, array2.length].concat(array2))console.log(array2)// this logs [[], [], [4], [], [null]]// what is should log is [[2], [], [4,5], [], [null]]
查看完整描述

4 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

通过覆盖合并


编写泛型函数的好处是巨大的。我正在使用在另一篇文章中写的,不需要修改来支持您当前的需求 -merge


// main.js


import { merge } from './util'


const array1 = [[2], [], [3,5], [], [1]]

const array2 = [[], [], [4], [], [null]]


const result =

  merge(array1, array2)


console.log(JSON.stringify(result))

// [[2],[],[4,5],[],[null]]

merge很有帮助,因为它可以直观地处理任何可以想象到的形状的嵌套对象和数组(甚至是稀疏数组!) -


// util.js

const isObject = x =>

  Object(x) === x


const mut = (o = {}, [ k, v ]) =>

  (o[k] = v, o)


const merge = (left = {}, right = {}) =>

  Object

    .entries(right)

    .map

      ( ([ k, v ]) =>

          isObject(v) && isObject(left[k])

            ? [ k, merge(left[k], v) ]

            : [ k, v ]

      )

    .reduce(mut, left)


export { merge }

展开下面的代码段,以在您自己的浏览器中验证结果 -

// util.js


const isObject = x =>

  Object (x) === x


const mut = (o = {}, [ k, v ]) =>

  (o[k] = v, o)


const merge = (left = {}, right = {}) =>

  Object

    .entries(right)

    .map

      ( ([ k, v ]) =>

          isObject(v) && isObject(left[k])

            ? [ k, merge (left[k], v) ]

            : [ k, v ]

      )

    .reduce(mut, left)

// export { merge }


// main.js

// impor { merge } from './util'

const array1 = [[2], [], [3,5], [], [1]]

const array2 = [[], [], [4], [], [null]]


const result =

  merge(array1, array2)


console.log(JSON.stringify(result))

// [[2],[],[4,5],[],[null]]

不可变合并


在本例中,我们的函数将永久更改其中一个输入数组。这是一个变体,它接受任意数量的对象/数组,并允许我们轻松创建新数组,而无需更改任何输入mergearray1merge


const array1 = [[2], [], [3,5], [], [1]]

const array2 = [[], [], [4], [], [null]]


const result =

  merge([], array1, array2)


console.log("result:", JSON.stringify(result)) // [[2],[],[4,5],[],[null]]

console.log("array1:", JSON.stringify(array1)) // [[2],[],[3,5],[],[1]]

console.log("array2:", JSON.stringify(array2)) // [[],[],[4],[],[null]]

以下是修改后的模块可能的外观 -util


// util.js


const isArray =

  Array.isArray


const isObject = x =>

  Object(x) === x


const merge2 = (l = null, r = null) => // <- private; not exported

  isArray(l) && isArray(r)

    ? merge([], l, r)

: isObject(l) && isObject(r)

    ? merge({}, l, r)

: r


const merge = (init = {}, ...all) =>  // <- public interface

  all.reduce(replace, init)


const replace = (r = {}, o = {}) =>

{ for (const [ k, v ] of Object.entries(o))

    r[k] = merge2(r[k], v)

  return r

}


export { merge }

这最初是为另一个问题写的,但从未发表过。我很高兴我有一个地方终于发布了它。享受!


展开下面的代码段以验证浏览器中的结果 -

//util.js

const isArray =

  Array.isArray


const isObject = x =>

  Object(x) === x


const merge2 = (l = null, r = null) =>

  isArray(l) && isArray(r)

    ? merge([], l, r)

: isObject(l) && isObject(r)

    ? merge({}, l, r)

: r


const merge = (init = {}, ...all) =>

  all.reduce(replace, init)


const replace = (r = {}, o = {}) =>

{ for (const [ k, v ] of Object.entries(o))

    r[k] = merge2(r[k], v)

  return r

}

// export { merge }


// main.js

// import { merge } from './util'

const array1 = [[2], [], [3,5], [], [1]]

const array2 = [[], [], [4], [], [null]]


const result =

  merge([], array1, array2)


console.log("result:", JSON.stringify(result))

// [[2],[],[4,5],[],[null]]


console.log("array1:", JSON.stringify(array1))

// [[2],[],[3,5],[],[1]]


console.log("array2:", JSON.stringify(array2))

// [[],[],[4],[],[null]]


查看完整回答
反对 回复 2022-09-02
?
Qyouu

TA贡献1786条经验 获得超11个赞

您需要一个函数来获取两个数组并合并它们:


merge_arrays([3,5], [4]);

//=> [4,5]


merge_arrays([3,5], []);

//=> [3,5]


merge_arrays([3,5], [,7]);

//=> [3,7]


merge_arrays([3,5], [,7,8]);

//=> [3,7,8]

下面是一个可能的实现:


const merge_arrays =

  ([xh, ...xt], [yh, ...yt], ret = []) =>

      xh === undefined && yh === undefined ? ret

    : yh === undefined                     ? merge_arrays(xt, yt, [...ret, xh])

                                           : merge_arrays(xt, yt, [...ret, yh]);

有了这个,你可以 - 假设 array1 和 array2 具有相同的长度 - 映射并应用于当前元素和位于同一索引处的元素:array1merge_arraysarray2


const array1 = [[2], [], [3,5], [], [1]];

const array2 = [[], [], [4], [], [null]];


array1.map((arr, idx) => merge_arrays(arr, array2[idx]));

//=> [[2], [], [4,5], [], [null]]


查看完整回答
反对 回复 2022-09-02
?
胡子哥哥

TA贡献1825条经验 获得超6个赞

您可以映射两次:

array1.map((arr, i) => arr.map((v, j) => j in array2[i] ? array2[i][j] : v));


查看完整回答
反对 回复 2022-09-02
?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

老式的,但你可以看到整个过程:)


编辑:添加了一行。


const array1 = [[2], [], [3,5], [], [1]];

const array2 = [[], [], [4], [], [null]];


/*

// verbose way

if (array1.length == array2.length) {

  for (var i=0; i < array1.length; i++) {

    if (array1[i].length > 0) {

      array1[i] = array2[i];

    }

  }

}

*/


// concise way

newArr = array1.map((el, i) => el.length > 0 ? array2[i] : el);


console.log(newArr);


查看完整回答
反对 回复 2022-09-02
  • 4 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信