将数组与对象属性相匹配



我有一个属性如下的对象:

{
maj6: { chromatic: [ 0, 4, 7, 9 ] },
min6: { chromatic: [ 0, 3, 7, 9 ] },
maj7: { chromatic: [ 0, 4, 7, 11 ] },
min7: { chromatic: [ 0, 3, 7, 10 ] },
minmaj7: { chromatic: [ 0, 3, 7, 11 ] },
dom7: { chromatic: [ 0, 4, 7, 10 ] },
maj9: { chromatic: [ 0, 4, 7, 11, 14 ] },
dom9: { chromatic: [ 0, 4, 7, 10, 14 ] },
maj: { chromatic: [ 0, 4, 7 ] },
min: { chromatic: [ 0, 3, 7 ] },
aug: { chromatic: [ 0, 4, 8 ] },
dim: { chromatic: [ 0, 3, 6 ] }
}

我正在计算一个数组,例如[0,4,7],我正试图将其与上述对象属性之一匹配。我正试图使用find函数来实现这一点,如以下代码片段所示:

matchParsedToChord() {
const result = this.blocks //returns larger payload
.map(block => block.chromatic) // returns array [0,4,7,4,7,7,7,4]
.filter((v,i,arr) => arr.indexOf(v) === i) //removes redundancies  [0,4,7]
.find(v => { //attempts to 
v === Object.keys(chordDefinitions).map(key => chordDefinitions[key].chromatic)
})
console.log(result)
}

我的问题是Object.keys逻辑返回整个数组,而我希望进行逐元素比较。

我想返回与数组关联的对象属性,例如:

maj: { chromatic: [ 0, 4, 7 ] }

非常感谢

这将返回所有具有您要查找的模式的和弦。它只是将数组展平,然后查找indexOf来组装所有匹配项。可以作为严格(完全匹配(或包含(所有部分匹配(运行

const a = {
maj6: { chromatic: [ 0, 4, 7, 9 ] },
min6: { chromatic: [ 0, 3, 7, 9 ] },
maj7: { chromatic: [ 0, 4, 7, 11 ] },
min7: { chromatic: [ 0, 3, 7, 10 ] },
minmaj7: { chromatic: [ 0, 3, 7, 11 ] },
dom7: { chromatic: [ 0, 4, 7, 10 ] },
maj9: { chromatic: [ 0, 4, 7, 11, 14 ] },
dom9: { chromatic: [ 0, 4, 7, 10, 14 ] },
maj: { chromatic: [ 0, 4, 7 ] },
min: { chromatic: [ 0, 3, 7 ] },
aug: { chromatic: [ 0, 4, 8 ] },
dim: { chromatic: [ 0, 3, 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,4,7", false);
console.log('Contains', matches);
// strict
matches = getPattern("0,4,7", true);
console.log('Strict', matches);

使用数组#every((并匹配长度。目前还不清楚你想要的结果是什么,所以这可能需要根据你的期望进行修改

const data ={
maj6: { chromatic: [ 0, 4, 7, 9 ] },
min6: { chromatic: [ 0, 3, 7, 9 ] },
maj7: { chromatic: [ 0, 4, 7, 11 ] },
min7: { chromatic: [ 0, 3, 7, 10 ] },
minmaj7: { chromatic: [ 0, 3, 7, 11 ] },
dom7: { chromatic: [ 0, 4, 7, 10 ] },
maj9: { chromatic: [ 0, 4, 7, 11, 14 ] },
dom9: { chromatic: [ 0, 4, 7, 10, 14 ] },
maj: { chromatic: [ 0, 4, 7 ] },
min: { chromatic: [ 0, 3, 7 ] },
aug: { chromatic: [ 0, 4, 8 ] },
dim: { chromatic: [ 0, 3, 6 ] }
}
const arr =  [0,4,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)

您不应该在从this.blocks获得的数组上使用find()。这只会返回一个像3这样的数字。

我假设您希望返回chordDefinitions中与整个数组匹配的条目。因此,您应该将该数组放入一个变量中,然后在chordDefinitions中搜索相等的chromatic属性。

我已经将其转换为Set,以删除重复项并提高搜索效率。

function matchParsedToChord() {
const chord = new Set(
this.blocks //returns larger payload
.map(block => block.chromatic) // returns array [0,4,7,4,7,7,7,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)
}

你的意思是这样的吗?编辑为使用reduce获得所需的返回

const a = {
maj6: { chromatic: [ 0, 4, 7, 9 ] },
min6: { chromatic: [ 0, 3, 7, 9 ] },
maj7: { chromatic: [ 0, 4, 7, 11 ] },
min7: { chromatic: [ 0, 3, 7, 10 ] },
minmaj7: { chromatic: [ 0, 3, 7, 11 ] },
dom7: { chromatic: [ 0, 4, 7, 10 ] },
maj9: { chromatic: [ 0, 4, 7, 11, 14 ] },
dom9: { chromatic: [ 0, 4, 7, 10, 14 ] },
maj: { chromatic: [ 0, 4, 7 ] },
min: { chromatic: [ 0, 3, 7 ] },
aug: { chromatic: [ 0, 4, 8 ] },
dim: { chromatic: [ 0, 3, 6 ] }
}
const find = (obj, match = [0,4,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))

最新更新