将数组转换为关联数组

huangapple go评论60阅读模式
英文:

Typescript convert array to associative array

问题

我有一个数组我想将其转换为关联数组并需要一些有关语法的帮助我想要使关联数组为只读

我是一个TypeScript新手如果这是一个非常基本的问题我很抱歉

给定一个关联数组的数组

```javascript
interface Greeting {
    name: String,
    punctuation?: String,
}

const GreetingArray: ReadonlyArray<Greeting> = [
    {name: "noob", punctuation: "!"},
    {name: "sam", punctuation: "."}
]

我尝试使用 new Map<> 并遍历元素,但我不确定如何使其与只读映射或通用的只读关联数组兼容。

我想要的是将我的关联数组的数组转换为一个对象,支持字典/哈希映射的行为以进行查找,使用 .name 作为键,完整的关联数组作为对象({"noob": {name: "noob", punctuation: "!"}, "sam": {name: "sam", punctuation: "."}})。


<details>
<summary>英文:</summary>

I have an array that I want to turn into an associative array and need some help on the syntax.  I&#39;d like to make the associative array read only.

I&#39;m a typescript noob and apologize if this is a really basic question.


Given an array of associative arrays:

interface Greeting {
name: String,
punctuation?: String,
}

const GreetingArray: ReadonlyArray<Greeting> = [
{name: "noob", punctuation: "!"},
{name: "sam", punctuation: "."}
]


I fumbled my way into using `new Map&lt;&gt;` and `forEach`ing over elements, but I&#39;m not sure how to make this compatible with ReadOnly map or general read only associative array.


What I&#39;d like is to be able to convert my array of associative arrays into an object that supports dict/hashmap-like behavior for lookups, using the `.name` as the key and full associative array as an object (`{&quot;noob&quot;: {name: &quot;noob&quot;, punctuation: &quot;!&quot;}, &quot;sam&quot;: {name: &quot;sam&quot;, punctuation: &quot;.&quot;}}`).



edit: removed distracting failed attempt per suggestion :)

edit2: removing even more unhelpful text from my question &#128517;

</details>


# 答案1
**得分**: 3

你正在寻找的类型类似于:

```typescript
interface GreetingDict {
    readonly [k: string]: Greeting;
}

这个类型具有一个 string 索引签名,这意味着它可以有任意数量的 string 类型的键,每个键都应该有一个关联的 Greeting 类型的属性。并且它是一个 readonly 索引签名,这意味着编译器会阻止人们对它进行写操作。 (请注意,它只是阻止此类写入,并不能保证写入无法发生;它仅在编译时起作用,而 TypeScript 认为 readonly 属性可以相互赋值给非 readonly 属性,因此很容易通过使用类型不是 readonly 的引用来绕过这一点,对同一对象进行写入。)


给定一个类似于以下的 Greeting 数组:

const greetingArray: ReadonlyArray<Greeting> = [
    { name: "noob", punctuation: "!" },
    { name: "sam", punctuation: "." }
]

你可以通过将它映射(map)为一个键值对数组,然后使用Object.fromEntries() 方法将其转换为一个单一的对象。

const myReadOnly: GreetingDict = Object.fromEntries(greetingArray.map(g => [g.name, g]));

你可以验证这是否按预期工作:

console.log(myReadOnly)
/* {
  "noob": {
    "name": "noob",
    "punctuation": "!"
  },
  "sam": {
    "name": "sam",
    "punctuation": "."
  }
} */

[Playground链接到代码](https://www.typescriptlang.org/play?moduleResolution=99&amp;target=99&amp;jsx=0&amp;module=1&amp;isolatedModules=false#code/PTAEFcGcFNUgXATgSwHYHNQENUBNSoD28oAykmugDRzSwAW88ADpAFwgDu3AdPAJ7NokAMYpm8ADY50PQonTBchEZGD0cuAEaFCAayXQR0xFnjJCqALQAzZJOFLCVyFc1Xl1+JB6MAtpIAxKjgflrQiC4UGFY6hA44Lvxh8W54VoRaAFZG8ABQeWjwETZYIrAA4oh05higAN55oARYftBscNHUTaDM4Kgi8OBmFqgA-B0IKBhUeQC+BSKWCKDo1dC16ACCiKb8HQBK0Fiekvw7ewA8VTWUAHygALygANo99S1tHQBERJnfND6AyGI0sPwAhN9QHNZs0PqhWu1QN9IK0Ab1+oNhuYwcieFCFgBdApFEplSrrTYAEWQgwaPWqJ0sZ1eekmXUJHRuG0o8zyS1QKz8-COJwA8qgzlzKZQaXTHj0xdlcjwbIhCH4AKKoCjCAAUa1uGAuWH4PD8WGYBqe d݂9csegRbRo6EJAEoXQBuRbLeLQHiSQjoPXC0W4CVnF15YAAKnpzV+ui03w6jWacYd0CTyL+idhqe+QKxoNQme+kJ6MJ6KLRyZ6acRJdRfgBteRBZBOOLP3x5fmzSjwAKQA)

英文:

The type you're looking for is something like

interface GreetingDict {
    readonly [k: string]: Greeting
}

which has a string index signature meaning that it could have any number of string-valued keys, each of which should have a Greeting-valued property associated with it. And it's a readonly index signature meaning that the compiler will discourage people from doing any writes into it. (Note that it just discourages such writes and does not guarantee that the writes cannot happen; it's a compile-time only construct, and TypeScript considers readonly properties to be mutually assignable to non-readonly properties, so it's easy enough to circumvent this by writing to the same object using a reference whose type isn't readonly.)


Given an array of Greetings like

const greetingArray: ReadonlyArray&lt;Greeting&gt; = [
    { name: &quot;noob&quot;, punctuation: &quot;!&quot; },
    { name: &quot;sam&quot;, punctuation: &quot;.&quot; }
]

you can convert it into a GreetingDict by mapping it to an array of key-value pairs, and then using the Object.fromEntries() method to
transform it to a single object.

const myReadOnly: GreetingDict =
  Object.fromEntries(greetingArray.map(g =&gt; [g.name, g]));

You can verify that this works as expected:

console.log(myReadOnly)
/* {
  &quot;noob&quot;: {
    &quot;name&quot;: &quot;noob&quot;,
    &quot;punctuation&quot;: &quot;!&quot;
  },
  &quot;sam&quot;: {
    &quot;name&quot;: &quot;sam&quot;,
    &quot;punctuation&quot;: &quot;.&quot;
  }
}  */

Playground link to code

huangapple
  • 本文由 发表于 2023年3月7日 21:00:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75662312.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定