为什么不接受Map构造函数的可迭代元组数组?

时间:2017-05-21 16:27:07

标签: javascript dictionary ecmascript-6 tuples iterable

我在Javascript中创建了一个实现Iterable协议的元组类型。现在转换为Map

应该很容易
const Tuple = (...args) => {
  const Tuple = f => f(...args);
  Tuple[Symbol.iterator] = () => args[Symbol.iterator]();
  return Tuple;
};

new Map([Tuple(1, "a"), Tuple(2, "b")]); // Map {undefined => undefined}

相反,我必须手动进行转换:



const Tuple = (...args) => {
  const Tuple = f => f(...args);
  Tuple[Symbol.iterator] = () => args[Symbol.iterator]();
  return Tuple;
};

const toArray = tx => tx((...args) => args);

const Map_ = (...pairs) => {
  return new Map(pairs.map(pair => toArray(pair)));
};

const map = Map_(Tuple(1, "a"), Tuple(2, "b"));

console.log(map.get(1), map.get(2)); // "a" "b"




似乎Map只接受外部复合类型的Iterable,而不是内部对。我错过了什么?还有另一种方法可以实现转换吗?

3 个答案:

答案 0 :(得分:4)

Map的构造函数被定义为接受任何Iterable的键/值对象,其中键/值对象被定义为属性0是键和属性1的对象是价值。它没有说明允许Iterables用于键/值对象。 (如果确实允许它们并且定义它会将迭代器调用两次,那可能会很酷,但是......那不是他们所做的。:-)而且更多复杂...)

如果我们查看the spec,如果Tuple支持属性0(对于密钥)和1(对于值),则// (Defined this way because you seemed to want a non-constructor) const TupleMethods = { get "0"() { return this.key; }, get "1"() { return this.value; } }; const Tuple = (key, value) => { const t = Object.create(TupleMethods); t.key = key; t.value = value; return t; } // Usage: const m = new Map([ Tuple("one", "uno"), Tuple("two", "due"), Tuple("three", "tre") ]); console.log(m.get("two")); // "due"将起作用。例如:

// (Defined this way because you seemed to want a non-constructor)
const TupleMethods = {};
Object.defineProperties(TupleMethods, {
    "0": {
        get() {
            return this.key;
        }
    },
    "1": {
        get() {
            return this.value;
        }
    }
});
const Tuple = (key, value) => {
    const t = Object.create(TupleMethods);
    Object.defineProperties(t, {
        key: {
            value: key
        },
        value: {
            value: value
        }
    });
    return t;
};

// Usage:
const m = new Map([
    Tuple("one", "uno"),
    Tuple("two", "due"),
    Tuple("three", "tre")
]);
console.log(m.get("two")); // "due"

在评论中你提到了不变性。也许:

template <typename T>
void gethdf(T * l, H5::H5File *  file,  char * name )
{
  H5::DataSet dataset = H5::DataSet(file->openDataSet(name));
  H5::DataType dt;

  if(typeid(T) == typeid(float) )
     dt = H5::PredType::NATIVE_FLOAT;

     ...

 dataset.read(l, dt);
} 

答案 1 :(得分:0)

  

我在Javascript中创建了一个实现Iterable协议的元组类型。

唐&#39;吨。元组具有不同的属性,它们具有固定的长度,并且每个元素具有(可以具有)其自己的类型,而(可迭代的)集合由相同类型的多个元素组成。当然,JavaScript并不关心类型(所有数组都是异构的),但作为程序员应该这样做。

  

为什么Map只接受外部复合类型的Iterable,而不接受内部对?

出于同样的原因。元素是或两元组,表示为数组(缺少其他数据结构,并且不必像迭代器结果那样引入一个简单)。它们总是有两个元素,可以[0][1]访问(它们甚至不需要.length!),并且绝对没有理由迭代它们。

答案 2 :(得分:-2)

&#13;
&#13;
const Tuple = (...args) => Object.entries({[args.shift()]: args.shift()});

const map = new Map(Tuple(0, "a").concat(Tuple(1, "b")));

console.log(map.get("0"), map.get("1"));
&#13;
&#13;
&#13;