如何从多个数组的匹配中创建对象

时间:2018-12-15 16:54:49

标签: javascript arrays object

给出var o = { "scsi0": "vm-101-disk-1.qcow2,size=32G", "scsi11": "vm-101-disk-2.qcow2,size=32G", "scsi2": "vm-101-disk-3.qcow2,size=32G" }; var max = Object.keys(o).reduce((m, k) => +m.replace(/\D/g, '') > +k.replace(/\D/g, '') ? m : m = k); console.log(max, +max.replace(/\D/g, ''))array1,我应该创建一个对象,其中属性和值来自两个数组之间的交集。

array2

是否有比此实现更好或更干净的方法?

6 个答案:

答案 0 :(得分:2)

目前尚不清楚该函数应该做什么,这使得它很难阅读。相反,您应该分离任务:

  const intersection = (a, b) => a.filter(it => b.includes(it));
  const toMap = (values, mapper) => Object.assign({}, ...values.map(value => ({ [mapper(value)]: value })));

  const matches = intersection(array1.map(it => it.toUpperCase()), array2);
  const result = toMap(matches, value => value.toLowerCase());

答案 1 :(得分:2)

您可以使用reduce()构建对象,仅在找到匹配项的地方添加键。

function objOfMatches(array1, array2, cb) {
  return array1.reduce((obj, item) => {
    if (array2.includes(cb(item))) obj[item] = cb(item)
    return obj
  }, {})

}


console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) {
  return str.toUpperCase();
}));

这很简单,但是它将具有O(n²)行为,因为includes会为array2中的每个项目浏览array1。对于较小的列表而言,这可能无关紧要,但是如果列表较大,则可能需要进行某种哈希(例如Set或对象)以使您不断地查询array2

类似的东西:

function objOfMatches(array1, array2, cb) {
  let set = new Set(array2)
  return array1.reduce((obj, item) => {
    if (set.has(cb(item))) obj[item] = cb(item)
    return obj
  }, {})

}


console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) {
  return str.toUpperCase();
}));

答案 2 :(得分:1)

您可以使用Set并映射新对象的通用部分。

这种方法需要两个循环,每个数组一个循环。

function objOfMatches(array1, array2) {
    var s = new Set(array1);

    return Object.assign(...array2.map(v => s.has(v) && { [v.toLowerCase()]: v }));
}
console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'].map(s => s.toUpperCase()), ['HI', 'Howdy', 'BYE', 'LATER', 'hello']));

答案 3 :(得分:0)

您可以使用即将到来的fromEntries巨大的警告-当前的浏览器兼容性仅是Firefox atm according to MDN

但是:只需映射两个数组以将它们合并,然后在合并后的数组上fromEntries即可得到对象。

function objOfMatches(arr1, arr2) {
  const merged = arr1.map((el, i) => [el, arr2[i]]);
  return Object.fromEntries(merged);
}

const result = objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello']);
console.log(result);

答案 4 :(得分:0)

您可以尝试

function objOfMatches(array1, array2, cb) {
    return array1.reduce((op,cur,i)=>{
      if(array2.includes(cur.toUpperCase())){
        op[cur] = array2[i];
      }
      return op;
    },{})
}
console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello']));
// should log: { hi: 'HI', bye: 'BYE', later: 'LATER' }

答案 5 :(得分:0)

基于练习中先前的自定义forEach和Reduce (在http://csbin.io/callbacks

function forEach(array, callback) {
    for(i = 0; i < array.length; i++){
        callback(array[i])
    }
}

function reduce(array, callback, initialValue) {
    for(let i of array){
        initialValue = callback(initialValue, i)
    }
    return initialValue
}

function objOfMatches(array1, array2, callback) {
    let index = 0
    return reduce(array1, (acc, el) => {
        if(callback(el) == array2[index]){
            acc[el] = array2[index]
        }
        index++
        return acc
    }, {})
}

如果您使用内置的reduce功能,则可以将索引自动传递给回调:

function objOfMatches(array1, array2, callback) {
    return array1.reduce((acc, el, index) => {
        if(callback(el) == array2[index]){
            acc[el] = array2[index]
        }
        return acc
    }, {})
}