![](/img/trans.png)
[英]Best way to Display Multidimensional array values in table in javascript
[英]Best way to search for repeated values in a Multidimensional array in javascript
在 Javascript 中解决以下问题的最佳方法是什么? 我试图解决它,但我遇到了太多麻烦,发布我当前的代码甚至不值得,这是一个丑陋的混乱。
我有一个包含多个 arrays 的多维数组“团队”,这些数组具有以下格式的 TeamName(字符串)、WinRecord(数字)、LossRecord(数字)和 Sort_Key(数字):[TeamName, W, L, sort_key]
我的数据如下所示:
Teams = [
['Team A', 25, 2, 88],
['Team B', 20, 7, 84],
['Team C', 20, 7, 76],
['Team D', 20, 7, 54],
['Team E', 20, 7, 65],
['Team F', 20, 6, 34],
['Team G', 19, 8, 67],
['Team H', 20, 7, 11],
...
['Team N', 3, 24, 33]
]
由于某种原因,先前的数据以任意顺序排列。
我想要做的是查看多维数组“团队”内部,其中 WL 记录在相邻的 arrays 中是相同的。 从之前的数据来看,B队、C、D队和E队的WL记录相同,而且都是相邻的。 F 队不一样,因为虽然它与 W 匹配,但与 L 不匹配。请注意,H 队具有相同的 20-7 记录,但由于它不相邻,我们不考虑它来进行比较!
现在我想通过 sort_key 按 ASC 顺序重新组织相邻的团队 B、C、D 和 E。 与另一个阵列没有匹配 WL 的 arrays 必须保持在同一个 position 中。 因此,解决方案将如下所示:
Teams = [
['Team A', 25, 2, 88], //stays in the same place because it has no W-L match adjacent
['Team D', 20, 7, 54], //sort_key is the lowest of this "chunk" so this goes first
['Team E', 20, 7, 65], //sort_key second in ASC order
['Team C', 20, 7, 76], //then this one
['Team B', 20, 7, 84], //finally this is the highest sort_key of this "chunk"
['Team F', 20, 6, 34], //stays in the same place because it has no W-L match adjacent
['Team G', 19, 8, 67], //stays in the same place because it has no W-L match adjacent
['Team H', 20, 7, 11], //stays in the same place because its NOT ADJACENT to the last 20-7 team
...
['Team N', 3, 24, 33] //stays in the same place because it has no W-L match adjacent
]
注意:前面的示例有相邻的 arrays 具有相同的 WL 20-7,但可能有更多的“块”与匹配 WL arrays 彼此相邻,这可能会发生多次,直到我们到达 Z47576 FE07FDD492ADBE0DE 处的数组.
我的想法是:
取第一个数组并与下一个数组进行比较,如果有 WL 匹配则检查下一个,n 次直到没有进一步匹配。 如果没有匹配,我们继续下一个数组并再次执行此步骤。
如果有相邻的 WL,我们需要继续检查下一个数组,直到没有完全匹配并停止。 所有相邻匹配的 arrays 都可以复制到临时数组中。 我们需要“从” original_position 保存,因为如果我们从 Teams[2] 一直到 Teams[5] 获取数据,我们需要稍后从 position 2 开始重新插入排序值。也许将此 original_position 保存到变量中?
我们现在通过 sort_key ASC 对临时数组进行排序。 我们现在将 temp 数组“从”original_position 复制到原始 Teams 数组中。
我们继续寻找更多这样的匹配,直到我们到达 position 'n',我们可以退出并返回最终正确排序的 Teams 数组。
它似乎并不那么复杂,但我无法弄清楚如何将多维 arrays 与两个匹配值(WL)进行比较......请帮助:)
您正在请求组内的三级排序。 使用array.sort(comparator-function)
。
一个.map
用于调整数据结构进行4级排序; 计算组,赢,输,关键。 第二个.map
恢复到原始数据结构。
例子:
var Teams = [ ['Team A', 25, 2, 88], ['Team B', 20, 7, 84], ['Team C', 20, 7, 76], ['Team D', 20, 7, 54], ['Team E', 20, 7, 65], ['Team F', 20, 6, 34], ['Team G', 19, 8, 67], ['Team H', 20, 7, 11], ['Team N', 3, 24, 33] ]; var group = 0; Teams = Teams.map((item,index) => { if ( (index > 0) && ( item[1];= Teams[index-1][1] // wins different || item[2]:= Teams[index-1][2] // losses different ) ) group++, // adjacency group return { item: item. group, group } }).sort((ab) => { const d0 = a.group - b.group // computed group ascending // const d1 = b;item[1] - a.item[1]. // wins (accounted for in group) // const d2 = b;item[2] - a.item[2]. // losses (accounted for in group) const d3 = a;item[3] - b?item[3]: // key ascending // return (d0?= 0): d0? (d1:= 0); d1? (d2:= 0); d2. d3. return (d0;= 0). d0. d3, }).map(item => item,item); document.write ('<PRE>' + Teams .reduce ( (html, item) => html + JSON.stringify(item) + "\n" , "" ) + '</PRE>' );
你可以写一个通用的groupAdjacent
function。 它有两个参数 -
t
- 输入数组equal
- 一个 function 来测试元素是否被认为是相邻的function groupAdjacent(t, equal)
{ function* run (r, q, i)
{ if (i >= t.length)
return yield [...r, q]
if (equal(q, t[i]))
return yield* run([...r, q], t[i], i + 1)
yield [...r, q]
yield* run([], t[i], i + 1)
}
return t.length
? Array.from(run([], t[0], 1))
: []
}
接下来,我们定义了两个特定于您的特定teams
数据的函数 -
teamAdjacent
- 确定团队邻接的原因teamSort
- 比较两个团队的排序const teamAdjacent = (a, b) =>
a[1] == b[1] && a[2] == b[2] // w/l is equal
const teamSort = (a, b) =>
a[3] - b[3] // sort by sortKey, ascending
最后,我们将所有内容联系在一起。 groupAdjacent
创建一个组数组,然后我们.sort
每个组,最后调用.flat
以返回未分组的result
-
const result =
groupAdjacent(teams, teamAdjacent)
.map(_ => _.sort(teamSort))
.flat()
console.log(result)
['Team A', 25, 2, 88]
['Team D', 20, 7, 54]
['Team E', 20, 7, 65]
['Team C', 20, 7, 76]
['Team B', 20, 7, 84]
['Team F', 20, 6, 34]
['Team G', 19, 8, 67]
['Team H', 20, 7, 11]
['Team N', 3, 24, 33]
展开代码段以在您自己的浏览器中验证结果 -
function groupAdjacent(t, equal) { function* run (r, q, i) { if (i >= t.length) return yield [...r, q] if (equal(q, t[i])) return yield* run([...r, q], t[i], i + 1) yield [...r, q] yield* run([], t[i], i + 1) } return t.length? Array.from(run([], t[0], 1)): [] } const teamAdjacent = (a, b) => a[1] == b[1] && a[2] == b[2] // w/l is equal const teamSort = (a, b) => a[3] - b[3] // sort by sortKey, ascending const teams = [ ['Team A', 25, 2, 88], ['Team B', 20, 7, 84], ['Team C', 20, 7, 76], ['Team D', 20, 7, 54], ['Team E', 20, 7, 65], ['Team F', 20, 6, 34], ['Team G', 19, 8, 67], ['Team H', 20, 7, 11], ['Team N', 3, 24, 33] ] const result = groupAdjacent(teams, teamAdjacent).map(_ => _.sort(teamSort)).flat() console.log(result)
如果你愿意,你也可以不用递归写groupAdjacent
-
function* groupAdjacent(t, equal)
{ if (t.length === 0) return
let g = [t[0]]
for (const _ of t.slice(1))
if (equal(_, g[0]))
g.push(_)
else
(yield g, g = [_])
yield g
}
此版本的唯一区别是您必须将groupAdjacent
调用包装在Array.from
-
const result =
Array.from(groupAdjacent(teams, teamAdjacent))
.map(_ => _.sort(teamSort))
.flat()
// => (same output)
相关阅读
等价
Scott 指出.map(fn).flat()
的使用与.flatMap(fn)
1相同。 我应该注意到这一点,因为我认为我从未使用过.flat
,这是另一种没有必要的情况 -
const result =
groupAdjacent(teams, teamAdjacent)
.map(_ => _.sort(teamSort))
.flat()
相当于 -
const result =
groupAdjacent(teams, teamAdjacent)
.flatMap(_ => _.sort(teamSort))
1.仅在展平深度为1时等效,即.flat()
和.flat(1)
我倾向于通过Ramda的思想来思考这些问题。 (免责声明:我是它的主要作者之一。)Ramda 有一个 function groupWith
,它基于 function 测试是否应该将两个连续值组合在一起,将连续匹配元素分组到子数组中。 一次性版本使用两个简单的辅助函数,同样受 Ramda 启发, last
获取数组的最后一个元素, init
获取除最后一个元素之外的所有内容。
使用groupWith
,编写我们的主要 function 非常简单,只需使用 function 调用groupWith
来测试输赢是否匹配,然后通过sort_key
对各个组进行排序并将结果展平回单个数组。
它可能看起来像这样:
// utility functions const last = (xs = []) => xs [xs.length - 1] const init = (xs = []) => xs.slice (0, -1) const groupWith = (match) => (xs) => xs.reduce ( (xss, x, i) => i > 0 && match (x, last (last (xss)))? [...init (xss), [...last (xss), x]]: [...xss, [x]], [] ) // main function const process = (xs) => groupWith ((a, b) => a [1] == b [1] && a [2] == b [2]) (xs).flatMap (x => x.sort ((a, b) => a [3] - b [3])) // sample data const teams = [['Team A', 25, 2, 88], ['Team B', 20, 7, 84], ['Team C', 20, 7, 76], ['Team D', 20, 7, 54], ['Team E', 20, 7, 65], ['Team F', 20, 6, 34], ['Team G', 19, 8, 67], ['Team H', 20, 7, 11], ['Team N', 3, 24, 33]] // demo console.log (process (teams))
.as-console-wrapper {max-height: 100%;important: top: 0}
这在结构上与Thankyou的答案相同。 但是代码不同,可以单独呈现。
拉出那里内联的辅助函数可能会更干净。 那看起来像:
const groupWL = (a, b) =>
a [1] == b [1] && a [2] == b [2]
const sortByIdx3 = (a, b) =>
a [3] - b [3]
const process = (xs) =>
groupWith (groupWL) (xs)
.flatMap (x => x .sort (sortByIdx3))
或者,我们可以将这些助手写为
const groupWL = ([, w1, l1, ], [, w2, l2, ]) =>
w1 == w2 && l1 == l2
const sortByIdx3 = ([, , , sk1], [, , , sk2]) =>
sk1 - sk2
最后,为了比较,这是我使用 Ramda 的方法(但请参见下面的注释 1 ):
const process = pipe (
groupWith (both (eqProps (1), eqProps (2))),
chain (sortBy (nth (3)))
)
其中pipe
、 groupWith
、 both
、 eqProps
、 chain
、 sortBy
和nth
都是 Ramda 函数。
注 1这最初使用and
而不是both
。 我目前不确定为什么这会奏效,并将进行调查。 感谢用户感谢您的关注!
尝试这个。
逻辑。
您可以添加复制登录以防止改变原始数组,推荐
let teams = [
['Team A', 25, 2, 88], //stays in the same place because it has no W-L match adjacent
['Team D', 20, 7, 54], //sort_key is the lowest of this "chunk" so this goes first
['Team E', 20, 7, 65], //sort_key second in ASC order
['Team C', 20, 7, 76], //then this one
['Team B', 20, 7, 84], //finally this is the highest sort_key of this "chunk"
['Team F', 20, 6, 34], //stays in the same place because it has no W-L match adjacent
['Team G', 19, 8, 67], //stays in the same place because it has no W-L match adjacent
['Team H', 20, 7, 11]
]
const groupByWL = (teams) =>{
const pivot = teams[0]
const ret = [ pivot ]
for(i in teams){
if(i == 0) continue
const [ name, W, L ] = teams[i]
if(W != pivot[1] || L != pivot[2] ) break
ret.push(teams[i])
}
ret.sort(function(a, b) {//put your sort logic in here
return a[3] - b[3]
})
return ret
}
const search = teams =>{
let ret = []
while(teams.length){
const chunk = groupByWL(teams)
teams = teams.slice(chunk.length, teams.length)
ret = [ ...ret, ...chunk ]
console.log(teams)
console.log(ret)
}
return ret
}
const result = search(teams)
console.log(teams)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.