在 Javascript 中,字符串使用来自不同字段集的排序来连接字段集



很难清楚地命名这个问题,但我们在Javascript中有一个对象数组,看起来像:

[
{
a1: 234,
a2: 493,
a3: 123,
a1Rk: 4,
a2Rk: 9,
a3Rk: 6
},{
a1: 455,
a2: 654,
a3: 982,
a1Rk: 7,
a2Rk: 2,
a3Rk: 2
}
]

我们想对字段进行字符串连接a1, a2, a3,但是字符串连接顺序基于a1Rk, a2Rk, a3Rk列。如果Rk列是并列的,则领带将转到较低的属性值。在上面的示例中,我们尝试输出以下内容:

[
{
a1: 234,
a2: 493,
a3: 123,
a1Rk: 4,
a2Rk: 9,
a3Rk: 6,
output: '234-123-493'
},{
a1: 455,
a2: 654,
a3: 982,
a1Rk: 7,
a2Rk: 2,
a3Rk: 2,
output: '654-982-455'
}
]

在第一个对象中,输出a1-a3-a2,因为 a1Rk<a2Rk。在第二个对象中,输出a2-a3-a1,因为><982。>

这似乎有效,尽管我们担心它在更大的对象数组上的性能:

zed = [
{
a1: 234,
a2: 493,
a3: 123,
a1Rk: 4,
a2Rk: 9,
a3Rk: 6
},{
a1: 455,
a2: 654,
a3: 982,
a1Rk: 7,
a2Rk: 2,
a3Rk: 2
}
]
let sort123 = (obj) => {
let arr = [
{ key: 1, val: obj.a1, rk: obj.a1Rk },
{ key: 2, val: obj.a2, rk: obj.a2Rk },
{ key: 3, val: obj.a3, rk: obj.a3Rk }
];
let sortedArr = arr.sort((a, b) => { if (a.rk === b.rk) { return a.val > b.val ? 1 : -1; }; return a.rk > b.rk ? 1 : -1; });
let lineupId = '';
sortedArr.forEach(row => lineupId = `${lineupId}-${row.val}`);
lineupId = lineupId.slice(1);
return lineupId;
};
let output = zed.map(row => { return { ...row, output: sort123(row) }})
console.log(output)

const someData = [
{
a1: 234,
a2: 493,
a3: 123,
a1Rk: 4,
a2Rk: 9,
a3Rk: 6
},{
a1: 455,
a2: 654,
a3: 982,
a1Rk: 7,
a2Rk: 2,
a3Rk: 2
}
];

const out = someData.map(d => {
const order = ['a1', 'a2', 'a3'].sort((a, b) => {
if (d[a + "Rk"] === d[b + "Rk"]) {
return d[a] - d[b];
} else {
return d[a + "Rk"] - d[b + "Rk"];
}
});
const output = order.map(o => d[o]).join("-");
return {...d, output};
});
console.log(out);

这是一个由四部分组成的问题(如果包括验证,则为五个部分):

  1. 将实际值键与排名键区分开来
  2. 关联这些键处的值
  3. 验证相关数据(经常被忽略的步骤)
  4. 按排名值对相关列表进行排序
  5. 字符串
  6. 化实际值并连接字符串("-"以预期的数据格式)

正因为如此,我认为函数式方法是合适的,所以这里有一个应该继续很好地工作(适应)不同的键格式和排名后缀字符串等的方法。

我认为代码是不言自明的,但如果您有问题,请随时发表评论,我会回复。

'use strict';
function parseKey (key, suffix = 'Rk') {
const isRank = key.endsWith(suffix);
const name = isRank ? key.slice(0, -1 * suffix.length) : key
return {isRank, name};
}
function correlate (obj, suffix = 'Rk') {
const cache = {};
for (const [key, value] of Object.entries(obj)) {
const {isRank, name} = parseKey(key, suffix);
const entry = (cache[name] ??= {key});
entry[isRank ? 'rank' : 'value'] = value;
}
return Object.values(cache);
}
function validate (values) {
for (const obj of values) {
const hasExpectedValues = (
typeof obj.rank === 'number'
&& typeof obj.value === 'number'
);
if (!hasExpectedValues) {
const msg = `Matching pair not found in object: ${JSON.stringify(obj, null, 2)}`;
throw new Error(msg);
}
}
return values;
}
function sortByRank (a, b) {
return a.rank - b.rank;
}
function getSortedString (obj, suffix = 'Rk', joinStr = '-') {
const sorted = validate(correlate(obj, suffix)).sort(sortByRank);
return sorted.map(({value}) => String(value)).join(joinStr);
}
const input = [
{
a1: 234,
a2: 493,
a3: 123,
a1Rk: 4,
a2Rk: 9,
a3Rk: 6,
},
{
a1: 455,
a2: 654,
a3: 982,
a1Rk: 7,
a2Rk: 2,
a3Rk: 2,
},
];
const expected = [
{
a1: 234,
a2: 493,
a3: 123,
a1Rk: 4,
a2Rk: 9,
a3Rk: 6,
output: '234-123-493',
},
{
a1: 455,
a2: 654,
a3: 982,
a1Rk: 7,
a2Rk: 2,
a3Rk: 2,
output: '654-982-455',
},
];
const actual = input.map(obj => ({
...obj,
output: getSortedString(obj),
}));
console.log(JSON.stringify(actual) === JSON.stringify(expected)); // true

相关内容

  • 没有找到相关文章