将对象与键值匹配模式组合在一起。

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

Combine object with key values matching to pattern

问题

我正在尝试基于以S.1开头的键来拆分对象。

  1. const obj = {
  2. "S.1.1.0": "Hi",
  3. "S.1.1.1": "what is your name",
  4. "S.1.1.2": "Can we meet",
  5. "S.2.1.1": "what is the time now",
  6. "S.2.1.2a": "It is 6 PM",
  7. "S.3.1.1b": "where do you live",
  8. "S.3.1.2": "how is the weather",
  9. "S.3.1.3": "it is very cold",
  10. "S.3.1.3b": "yes",
  11. }
  12. const result = Object.entries(obj).reduce((a, [key, val]) => {
  13. const [s, k, v] = key.split('.')
  14. const item = a.find(({ key: itemkey }) => itemkey === k)
  15. console.log(item)
  16. if (item) {
  17. item[v] = val
  18. } else {
  19. a.push({
  20. key: k,
  21. [v]: val
  22. })
  23. }
  24. return a
  25. })
  26. console.log(result)

期望的输出是键值以S.1开头的组合在一起。键值是动态的,始终以S.1,S.2 ...开头。

  1. [{
  2. "S.1.1.0": "Hi",
  3. "S.1.1.1": "what is your name",
  4. "S.1.1.2": "Can we meet"
  5. },
  6. {
  7. "S.2.1.1": "what is the time now",
  8. "S.2.1.2a": "It is 6 PM"
  9. },
  10. {
  11. "S.3.1.1b": "where do you live",
  12. "S.3.1.2": "how is the weather",
  13. "S.3.1.3": "it is very cold",
  14. "S.3.1.3b": "yes"
  15. }]
英文:

I am trying to split the object based on the keys starting with a pattern like S.1.1.0.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const obj = {
  2. &quot;S.1.1.0&quot;: &quot;Hi&quot;,
  3. &quot;S.1.1.1&quot;: &quot;what is your name&quot;,
  4. &quot;S.1.1.2&quot;: &quot;Can we meet&quot;,
  5. &quot;S.2.1.1&quot;: &quot;what is the time now&quot;,
  6. &quot;S.2.1.2a&quot;: &quot;It is 6 PM&quot;,
  7. &quot;S.3.1.1b&quot;: &quot;where do you live&quot;,
  8. &quot;S.3.1.2&quot;: &quot;how is the weather&quot;,
  9. &quot;S.3.1.3&quot;: &quot;it is very cold&quot;,
  10. &quot;S.3.1.3b&quot;: &quot;yes&quot;,
  11. }
  12. const result = Object.entries(obj).reduce((a, [key, val]) =&gt; {
  13. const [s, k, v] = key.split(&#39;.&#39;)
  14. const item = a.find(({
  15. key: itemkey
  16. }) =&gt; itemkey === k)
  17. console.log(item)
  18. if (item) {
  19. item[v] = val
  20. } else {
  21. a.push({
  22. key: k,
  23. [v]: val
  24. })
  25. }
  26. return a
  27. }, [])
  28. console.log(result)

<!-- end snippet -->

Expecting the output to be like where key value starting with S.1 combined together. The key value is dynamic by always starts like S.1, S.2 ...

  1. [{
  2. &quot;S.1.1.0&quot;: &quot;Hi&quot;,
  3. &quot;S.1.1.1&quot;: &quot;what is your name&quot;,
  4. &quot;S.1.1.2&quot;: &quot;Can we meet&quot;
  5. },
  6. {
  7. &quot;S.2.1.1&quot;: &quot;what is the time now&quot;,
  8. &quot;S.2.1.2a&quot;: &quot;It is 6 PM&quot;
  9. },
  10. {
  11. &quot;S.3.1.1b&quot;: &quot;where do you live&quot;,
  12. &quot;S.3.1.2&quot;: &quot;how is the weather&quot;,
  13. &quot;S.3.1.3&quot;: &quot;it is very cold&quot;,
  14. &quot;S.3.1.3b&quot;: &quot;yes&quot;
  15. }
  16. ]

答案1

得分: 2

你可以使用reduce()方法创建一个带有mapping键作为索引的对象。然后使用Object.values(result)来获取所需的结果。

  1. [
  2. {
  3. "S.1.1.0": "Hi",
  4. "S.1.1.1": "what is your name",
  5. "S.1.1.2": "Can we meet"
  6. },
  7. {
  8. "S.2.1.1": "what is the time now",
  9. "S.2.1.2a": "It is 6 PM"
  10. },
  11. {
  12. "S.3.1.1b": "where do you live",
  13. "S.3.1.2": "how is the weather",
  14. "S.3.1.3": "it is very cold",
  15. "S.3.1.3b": "yes"
  16. }
  17. ]
英文:

You could reduce() to an object with the mapping key as index.

Then use Object.values(result) to get the desired result

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const obj = {
  2. &quot;S.1.1.0&quot;: &quot;Hi&quot;,
  3. &quot;S.1.1.1&quot;: &quot;what is your name&quot;,
  4. &quot;S.1.1.2&quot;: &quot;Can we meet&quot;,
  5. &quot;S.2.1.1&quot;: &quot;what is the time now&quot;,
  6. &quot;S.2.1.2a&quot;: &quot;It is 6 PM&quot;,
  7. &quot;S.3.1.1b&quot;: &quot;where do you live&quot;,
  8. &quot;S.3.1.2&quot;: &quot;how is the weather&quot;,
  9. &quot;S.3.1.3&quot;: &quot;it is very cold&quot;,
  10. &quot;S.3.1.3b&quot;: &quot;yes&quot;,
  11. }
  12. const result = Object.entries(obj).reduce((a, [key, val]) =&gt; {
  13. const mapping = key.split(&#39;.&#39;, 2).join(&#39;.&#39;);
  14. if (!a[mapping]) a[mapping] = { };
  15. a[mapping][key] = val;
  16. return a;
  17. }, {})
  18. const resultArray = Object.values(result);
  19. console.log(resultArray)

<!-- end snippet -->

Output:

  1. [
  2. {
  3. &quot;S.1.1.0&quot;: &quot;Hi&quot;,
  4. &quot;S.1.1.1&quot;: &quot;what is your name&quot;,
  5. &quot;S.1.1.2&quot;: &quot;Can we meet&quot;
  6. },
  7. {
  8. &quot;S.2.1.1&quot;: &quot;what is the time now&quot;,
  9. &quot;S.2.1.2a&quot;: &quot;It is 6 PM&quot;
  10. },
  11. {
  12. &quot;S.3.1.1b&quot;: &quot;where do you live&quot;,
  13. &quot;S.3.1.2&quot;: &quot;how is the weather&quot;,
  14. &quot;S.3.1.3&quot;: &quot;it is very cold&quot;,
  15. &quot;S.3.1.3b&quot;: &quot;yes&quot;
  16. }
  17. ]

答案2

得分: 0

如果要提高效率,可以创建一个Map,并根据keyFn指定的条件对每个键值对进行分组。

  1. const keyFn = (prop) => prop.match(/(?<=S\.)\d+/)[0]

示例

以下是代码的示例:

  1. const obj = {
  2. "S.1.1.0": "Hi",
  3. "S.1.1.1": "what is your name",
  4. "S.1.1.2": "Can we meet",
  5. "S.2.1.1": "what is the time now",
  6. "S.2.1.2a": "It is 6 PM",
  7. "S.3.1.1b": "where do you live",
  8. "S.3.1.2": "how is the weather",
  9. "S.3.1.3": "it is very cold",
  10. "S.3.1.3b": "yes",
  11. }
  12. const groupBy = (obj, keyFn) =>
  13. [...Object
  14. .entries(obj)
  15. .reduce((map, [prop, value]) => {
  16. const key = keyFn(prop), entries = map.get(key) ?? [];
  17. entries push([prop, value]);
  18. return map.set(key, entries);
  19. }, new Map)
  20. .values()]
  21. .map(entries => Object.fromEntries(entries))
  22. const grouped = groupBy(obj, (prop) => prop.match(/(?<=S\.)\d+/)[0]);
  23. console.log(grouped);

以下是使用lodash的相同示例。我创建了一个混入函数,接受一个对象和一个键模式。

  1. const obj = {
  2. "S.1.1.0": "Hi",
  3. "S.1.1.1": "what is your name",
  4. "S.1.1.2": "Can we meet",
  5. "S.2.1.1": "what is the time now",
  6. "S.2.1.2a": "It is 6 PM",
  7. "S.3.1.1b": "where do you live",
  8. "S.3.1.2": "how is the weather",
  9. "S.3.1.3": "it is very cold",
  10. "S.3.1.3b": "yes",
  11. }
  12. _.mixin({
  13. groupByPattern : (object, keyPattern) =>
  14. _.chain(obj)
  15. .entries()
  16. .groupBy(([prop, value]) => prop.match(keyPattern)?.[0])
  17. .values()
  18. .map(_.fromPairs)
  19. .value()
  20. });
  21. const grouped = _.groupByPattern(obj, /(?<=S\.)\d+/);
  22. console.log(grouped);

希望对你有帮助。

英文:

If you want to be efficient, you can build a Map and bin each key-value pair by criteria specified by the keyFn.

  1. const keyFn = (prop) =&gt; prop.match(/(?&lt;=S\.)\d+/)[0]

Example

Here is the code in action:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const obj = {
  2. &quot;S.1.1.0&quot;: &quot;Hi&quot;,
  3. &quot;S.1.1.1&quot;: &quot;what is your name&quot;,
  4. &quot;S.1.1.2&quot;: &quot;Can we meet&quot;,
  5. &quot;S.2.1.1&quot;: &quot;what is the time now&quot;,
  6. &quot;S.2.1.2a&quot;: &quot;It is 6 PM&quot;,
  7. &quot;S.3.1.1b&quot;: &quot;where do you live&quot;,
  8. &quot;S.3.1.2&quot;: &quot;how is the weather&quot;,
  9. &quot;S.3.1.3&quot;: &quot;it is very cold&quot;,
  10. &quot;S.3.1.3b&quot;: &quot;yes&quot;,
  11. }
  12. const groupBy = (obj, keyFn) =&gt;
  13. [...Object
  14. .entries(obj)
  15. .reduce((map, [prop, value]) =&gt; {
  16. const key = keyFn(prop), entries = map.get(key) ?? [];
  17. entries.push([prop, value]);
  18. return map.set(key, entries);
  19. }, new Map)
  20. .values()]
  21. .map(entries =&gt; Object.fromEntries(entries))
  22. const grouped = groupBy(obj, (prop) =&gt; prop.match(/(?&lt;=S\.)\d+/)[0]);
  23. console.log(grouped);

<!-- language: lang-css -->

  1. .as-console-wrapper { top: 0; max-height: 100% !important; }

<!-- end snippet -->

Here is the same, but it uses lodash. I created a mixin that takes an object and a key pattern.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const obj = {
  2. &quot;S.1.1.0&quot;: &quot;Hi&quot;,
  3. &quot;S.1.1.1&quot;: &quot;what is your name&quot;,
  4. &quot;S.1.1.2&quot;: &quot;Can we meet&quot;,
  5. &quot;S.2.1.1&quot;: &quot;what is the time now&quot;,
  6. &quot;S.2.1.2a&quot;: &quot;It is 6 PM&quot;,
  7. &quot;S.3.1.1b&quot;: &quot;where do you live&quot;,
  8. &quot;S.3.1.2&quot;: &quot;how is the weather&quot;,
  9. &quot;S.3.1.3&quot;: &quot;it is very cold&quot;,
  10. &quot;S.3.1.3b&quot;: &quot;yes&quot;,
  11. }
  12. _.mixin({
  13. groupByPattern : (object, keyPattern) =&gt;
  14. _.chain(obj)
  15. .entries()
  16. .groupBy(([prop, value]) =&gt; prop.match(keyPattern)?.[0])
  17. .values()
  18. .map(_.fromPairs)
  19. .value()
  20. });
  21. const grouped = _.groupByPattern(obj, /(?&lt;=S\.)\d+/);
  22. console.log(grouped);

<!-- language: lang-css -->

  1. .as-console-wrapper { top: 0; max-height: 100% !important; }

<!-- language: lang-html -->

  1. &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年3月15日 20:08:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75744490.html
匿名

发表评论

匿名网友

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

确定