如何解决将数组与对象属性匹配
我有一个具有如下属性的对象:
{
maj6: { chromatic: [ 0,4,7,9 ] },min6: { chromatic: [ 0,3,maj7: { chromatic: [ 0,11 ] },min7: { chromatic: [ 0,10 ] },minmaj7: { chromatic: [ 0,dom7: { chromatic: [ 0,maj9: { chromatic: [ 0,11,14 ] },dom9: { chromatic: [ 0,10,maj: { chromatic: [ 0,7 ] },min: { chromatic: [ 0,aug: { chromatic: [ 0,8 ] },dim: { chromatic: [ 0,6 ] }
}
我正在计算一个数组,例如 [0,7],我试图将其与上述对象属性之一匹配。我正在尝试使用 find 函数来实现这一点,如以下代码片段所示:
matchParsedToChord() {
const result = this.blocks //returns larger payload
.map(block => block.chromatic) // returns array [0,4]
.filter((v,i,arr) => arr.indexOf(v) === i) //removes redundancies [0,7]
.find(v => { //attempts to
v === Object.keys(chordDefinitions).map(key => chordDefinitions[key].chromatic)
})
console.log(result)
}
我的问题是 Object.keys 逻辑返回整个数组,而我想进行逐个元素的比较。
我想返回与数组关联的对象属性,例如:
maj: { chromatic: [ 0,7 ] }
非常感谢
解决方法
这将返回具有您正在寻找的模式的所有和弦。它只是将数组展平并查找 indexOf 以组合所有匹配项。可以将其作为严格(完全匹配)或包含(所有部分匹配)运行
const a = {
maj6: { chromatic: [ 0,4,7,9 ] },min6: { chromatic: [ 0,3,maj7: { chromatic: [ 0,11 ] },min7: { chromatic: [ 0,10 ] },minmaj7: { chromatic: [ 0,dom7: { chromatic: [ 0,maj9: { chromatic: [ 0,11,14 ] },dom9: { chromatic: [ 0,10,maj: { chromatic: [ 0,7 ] },min: { chromatic: [ 0,aug: { chromatic: [ 0,8 ] },dim: { chromatic: [ 0,6 ] }
}
function getPattern(pattern,strict) {
let b = []
for (const [key,value] of Object.entries(a)) {
let set = Object.values(value).flat().join(",") ;
if ((!strict && set.indexOf(pattern) !== -1) || (strict && set == pattern)) b.push({
[key]: value
})
}
if (strict && b.length>0) b = b[0];
return b;
}
// Contains (partial matches)
let matches = getPattern("0,7",false);
console.log('Contains',matches);
// strict
matches = getPattern("0,true);
console.log('Strict',matches);
你的意思是这样吗? 编辑以使用减少以获得所需的回报
const a = {
maj6: { chromatic: [ 0,6 ] }
}
const find = (obj,match = [0,7]) => {
return Object.keys(a)
.reduce((acc,k) => {
// If you want more loose match,just switch search direction
// like: match.every(m => obj[k].chromatic.includes(m)
if(obj[k].chromatic.every(m => match.includes(m))) {
acc[k] = obj[k];
}
return acc;
},{})
}
console.log(find(a))
使用 Array#every() 并匹配长度。虽然目前还不清楚您正在寻找什么结果,因此这可能需要根据您的期望进行修改
const data ={
maj6: { chromatic: [ 0,6 ] }
}
const arr = [0,7];
const entries = Object.entries(data).map(([k,v])=> [k,[...new Set(v.chromatic)]]);
const match = entries.find(([k,v])=> v.length === arr.length && arr.every(n => v.includes(n)))
console.log(match)
您不应该在从 find()
获得的数组上使用 this.blocks
。那只会返回一个像 3
这样的数字。
我假设您想返回 chordDefinitions
中匹配整个数组的条目。因此,您应该将该数组放入一个变量中,然后搜索 chordDefinitions
以获得相等的 chromatic
属性。
我已将其转换为 Set
以删除重复项并提高搜索效率。
function matchParsedToChord() {
const chord = new Set(
this.blocks //returns larger payload
.map(block => block.chromatic) // returns array [0,4]
); // Converting to Set removes duplicates
const chordSize = thisChord.size;
const result = Object.entries(chordDefinitions)
.find(([name,val]) => val.chromatic.length == chordSize && val.chromatic.every(v => chord.has(v)));
console.log(result)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。