如何实现类似解构赋值的功能?

时间:2018-02-12 09:25:54

标签: javascript arrays

如何实现类似解构赋值的功能?

Private Function find_RuleId_Column(page As String, strFind As String) As Range
Dim Gcell As Range
Set Gcell = Sheets(page).Range(Cells(1, 1), Cells(1, 1000)).find(What:=strFind, After:=ActiveCell, LookIn:=xlFormulas, Lookat _
   :=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
    False)
Set find_RuleId_Column = Gcell
End Function

foo?感谢。

3 个答案:

答案 0 :(得分:3)

这是基于

的解决方案
  • 使用第二个参数构建结构的JSON解析(使用技巧)
  • 两个数组中的递归平行下降,正如我的评论中所暗示的那样

function foo(arr, desc){
  var map = {};
  (function dive(arr, struct){
	struct.forEach((v, i) => {
		if (arr[i] === undefined) return;
		if (Array.isArray(v)) {
			dive(arr[i], v);
		} else {
			map[v] = arr[i];
		}
	});
  })(arr, JSON.parse(desc.replace(/\w+/g, '"$&"')));
  return map;
}

const res = foo([1, [2,3], [4, [6,[7,8]]]], '[a, [b, c], [d, [e, [f]]]]')
//                            ^ I removed not matching data here

console.log(res);

请注意,它假定数据与结构匹配。在一般情况下,最好添加错误处理。

答案 1 :(得分:2)

我的解决方案延迟了OP的原始请求,因为它接受一组键,而不是字符串。我认为它反映了“类似于解构分配”的要求比字符串更好。

这是一个递归解决方案,它接受一个值数组和一个具有相同形状的键数组,并使用Array.forEach()迭代键,并提取匹配值。

如果您想跳过某个值,请使用null作为密钥。

注意:您应该添加检查以确定形状相似,如果它们不同则抛出错误/使用默认值。

const destructor = (values, keys) => {
  const obj = {};
  
  const iterate = (values, keys) =>
    keys.forEach((key, i) => {
      if(key === null) {
        return;
      }
      if(Array.isArray(key)) iterate(values[i], key)
      else obj[key] = values[i]
    })
    
  iterate(values, keys)
  
  return obj;
}

const res = destructor([1, [2,3], [4,5,[6,[7,8]]]], ['a', ['b', 'c'], ['d', null, ['e', ['f']]]])

console.log(res)

答案 2 :(得分:0)

这是我的版本:

function destructor(values, keys) {
    const output = {};
    const kReg = /(?:"([^"]+)"|'([^']+)'|(\w+))/g;
    keys = keys.replace(/\{[^{}]+\}/g, match => match.replace(kReg, '"$1$2$3":"$1$2$3"'));
    keys = keys.replace(kReg, '"$1$2$3"');

    keys = JSON.parse(keys);

    function forAll(array, func, loc) {
        loc = loc || [];

        if (typeof array === 'object') {
            const nest = Object.assign({}, array);
            for (let a in nest) {
                if ({}.hasOwnProperty.call(nest, a)) {
                    nest[a] = forAll(nest[a], func, loc.concat(a));
                }
            }

            return nest;
        } else {
            return func(array, loc);
        }
    }
    function nestedGet(values, path) {
        const key = path.shift();

        return key === undefined ? values : (
            typeof values[key] === 'undefined' ? 
            undefined : nestedGet(values[key], path)
        );
    }

    forAll(keys, (elem, path) => {
        output[elem] = nestedGet(values, path)
    });

    return output;
}

此版本与其他版本的主要区别在于您还可以使用{key1, key2} esq解构。

例如:

destructor(
     [1, [2, 3], [4, {e:5, f:6}]],
    '[a, [b, c], [d, {e,   f  }]]'
);

成为:

{
    'a':1,
    'b':2,
    'c':3,
    'd':4,
    'e':5,
    'f':6
}

你的例子:

destructor(
     [1, [2, 3], [4, 5, [6, [7, 8]]]],
    '[a, [b, c], [d, [e, [f]]]]'
);

变为:

{
    'a':1,
    'b':2,
    'c':3,
    'd':4,
    'e':undefined,
    'f':undefined
}