英文:
Combine object with key values matching to pattern
问题
我正在尝试基于以S.1开头的键来拆分对象。
const obj = {
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet",
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM",
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes",
}
const result = Object.entries(obj).reduce((a, [key, val]) => {
const [s, k, v] = key.split('.')
const item = a.find(({ key: itemkey }) => itemkey === k)
console.log(item)
if (item) {
item[v] = val
} else {
a.push({
key: k,
[v]: val
})
}
return a
})
console.log(result)
期望的输出是键值以S.1开头的组合在一起。键值是动态的,始终以S.1,S.2 ...开头。
[{
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet"
},
{
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM"
},
{
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes"
}]
英文:
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 -->
const obj = {
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet",
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM",
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes",
}
const result = Object.entries(obj).reduce((a, [key, val]) => {
const [s, k, v] = key.split('.')
const item = a.find(({
key: itemkey
}) => itemkey === k)
console.log(item)
if (item) {
item[v] = val
} else {
a.push({
key: k,
[v]: val
})
}
return a
}, [])
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 ...
[{
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet"
},
{
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM"
},
{
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes"
}
]
答案1
得分: 2
你可以使用reduce()
方法创建一个带有mapping
键作为索引的对象。然后使用Object.values(result)
来获取所需的结果。
[
{
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet"
},
{
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM"
},
{
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes"
}
]
英文:
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 -->
const obj = {
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet",
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM",
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes",
}
const result = Object.entries(obj).reduce((a, [key, val]) => {
const mapping = key.split('.', 2).join('.');
if (!a[mapping]) a[mapping] = { };
a[mapping][key] = val;
return a;
}, {})
const resultArray = Object.values(result);
console.log(resultArray)
<!-- end snippet -->
Output:
[
{
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet"
},
{
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM"
},
{
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes"
}
]
答案2
得分: 0
如果要提高效率,可以创建一个Map
,并根据keyFn
指定的条件对每个键值对进行分组。
const keyFn = (prop) => prop.match(/(?<=S\.)\d+/)[0]
示例
以下是代码的示例:
const obj = {
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet",
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM",
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes",
}
const groupBy = (obj, keyFn) =>
[...Object
.entries(obj)
.reduce((map, [prop, value]) => {
const key = keyFn(prop), entries = map.get(key) ?? [];
entries push([prop, value]);
return map.set(key, entries);
}, new Map)
.values()]
.map(entries => Object.fromEntries(entries))
const grouped = groupBy(obj, (prop) => prop.match(/(?<=S\.)\d+/)[0]);
console.log(grouped);
以下是使用lodash的相同示例。我创建了一个混入函数,接受一个对象和一个键模式。
const obj = {
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet",
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM",
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes",
}
_.mixin({
groupByPattern : (object, keyPattern) =>
_.chain(obj)
.entries()
.groupBy(([prop, value]) => prop.match(keyPattern)?.[0])
.values()
.map(_.fromPairs)
.value()
});
const grouped = _.groupByPattern(obj, /(?<=S\.)\d+/);
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
.
const keyFn = (prop) => prop.match(/(?<=S\.)\d+/)[0]
Example
Here is the code in action:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const obj = {
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet",
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM",
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes",
}
const groupBy = (obj, keyFn) =>
[...Object
.entries(obj)
.reduce((map, [prop, value]) => {
const key = keyFn(prop), entries = map.get(key) ?? [];
entries.push([prop, value]);
return map.set(key, entries);
}, new Map)
.values()]
.map(entries => Object.fromEntries(entries))
const grouped = groupBy(obj, (prop) => prop.match(/(?<=S\.)\d+/)[0]);
console.log(grouped);
<!-- language: lang-css -->
.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 -->
const obj = {
"S.1.1.0": "Hi",
"S.1.1.1": "what is your name",
"S.1.1.2": "Can we meet",
"S.2.1.1": "what is the time now",
"S.2.1.2a": "It is 6 PM",
"S.3.1.1b": "where do you live",
"S.3.1.2": "how is the weather",
"S.3.1.3": "it is very cold",
"S.3.1.3b": "yes",
}
_.mixin({
groupByPattern : (object, keyPattern) =>
_.chain(obj)
.entries()
.groupBy(([prop, value]) => prop.match(keyPattern)?.[0])
.values()
.map(_.fromPairs)
.value()
});
const grouped = _.groupByPattern(obj, /(?<=S\.)\d+/);
console.log(grouped);
<!-- language: lang-css -->
.as-console-wrapper { top: 0; max-height: 100% !important; }
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论