FF 和 Chrome 排序函数有何不同?
由于某种原因,Firefox 和 Chrome 在其 JavaScript 引擎中似乎没有相同的排序方法算法。是否有一种明确的方法可以了解为什么或如何对这些数据进行不同的处理?在测试中发现简单的数组排序在其他浏览器中导致错误,这似乎有点奇怪,而它应该是一个非常简单的比较,不是吗?
这是我正在使用的代码:我收集一个 rss feed xml 文件,创建一个浅副本,以不处理符号或其他任何内容,以防万一,我只是插入标题包含“Special”的剧集,因为我并不关心在哪里他们被插入。然后,不要创建日期对象并进行一堆不必要的处理,因为 rss xml 中的每个剧集标题都以剧集编号开头,如“Ep.25:剧集名称”,我想我可以只解析字符串并使用整数值在“Ep”之间。和“:”按整数而不是日期时间对象排序。
由于某种原因,Firefox 没有给我提供与 Chrome 相同的结果,而且我无法理解无论哪个引擎正在处理 javascript,结果会有什么不同或错误。
的实时示例
请参阅 https://krisdriver.com/fg const EpisodeContainer = ()=>{
// random card background image if no specific index number is selected (select by map index)
const cardbg = ()=>{
let x = [bgselect]
return x[x.length-1]
}
// collect the rss feed info and start the async chain
async function loadingdata () {
return await rssdata
}
let data // collects results from async xml data collection
const epsperpage = 12 // PRODUCTION CONSIDERATION: consider allowing options for preloading, # per page, etc
const [datastate, setDataState] = useState(data)
const [epsLoaded, setEpsLoaded] = useState(false)
useEffect( ()=>{
loadingdata().then( res =>{
// eslint-disable-next-line react-hooks/exhaustive-deps
data = [...res]
let sortedEpisodes_byDate = [...data[0]] // create shallow copy, not reference
// start sorting the episodes by their data...
sortedEpisodes_byDate.sort( (x,y)=>{
// sorting episodes so part 1 and 2 are always in order
// exclude special episodes
if(!x.title.toUpperCase().includes('SPECIAL')){
// take the episode number from the title
let _temp = x.title.split(':') // take the "Ep.xx:" out of the title
let _temp2 = _temp[0].split('.') // take the number out of "Ep.xx"
let _temp3 = y.title.split(':')
let _temp4 = _temp3[0].split('.')
let [_x, _y] = [parseInt(_temp2[1]), parseInt(_temp4[1])] // compare integer values of ep numbers
if ( _x > _y) return 1 // sort
else return -1 // sort
}
else return -1 // just insert the specials
} )
let sorted = [...sortedEpisodes_byDate]
let _tmp = { eps: sorted.reverse(), channel: data[1] }
// return the sorted final output data object, without episodes being sectioned into pages
return _tmp
}).then( response=>{ // take final sorted data and start breaking it into sections for the DOM to render as pages...
if (datastate === undefined) {
// Organize episode info into pages
let numEpsDisplayedPerPage = epsperpage // referred to as 'x' in the comments of this scope
let numOfEps = response.eps.length
let episodePages = []
let pageloop = Math.ceil(numOfEps / numEpsDisplayedPerPage)
// for each page of x eps...
for(let i = 0; i < pageloop; i++){
let pageofepisodes = []
// for each of the x eps within page range...
for(let j = 0; j < numEpsDisplayedPerPage; j++ ){
// 'i*numEpsPerPage' is the index of Episode in the data array, the '+j' selects 1 through x on current page
pageofepisodes.push(response.eps[ (i*numEpsDisplayedPerPage) + j] )
}
episodePages.push([...pageofepisodes]) // make a shallow copy of the output array
}
// remove 'undefined' elements on the last page, if they exist
let len = episodePages.length-1
episodePages[len] = episodePages[len].filter( x => {
return x !== undefined
})
// finally, set the state to the data object which includes channel info, all episodes sorted, and paginated array
let tmp_obj = { ...response }
// remove time from publication date...
tmp_obj.eps.forEach( v => {
v.published = removeTimeFromPubDate(v.published).trim()
})
let tmp_ = { ...tmp_obj, pages: [...episodePages], sortselected: 1, currentPage: 0, buttonText: 'Newest First' }
// console.log(tmp_)
// ready, set state with data object sanitized
setDataState({ ...tmp_ })
// allow for useEffect to render contents
setEpsLoaded(true)
} // This all only runs on the first load, before the state is loaded. Data is parsed and split into pages
})
}, [])
// sanitize publish date to remove time and timezone from display cards next to episode titles
const removeTimeFromPubDate = (published) => published.split(':')[0].slice(0, -2)
" 这条线以上的“剧集”组件-------- “数据”导入到此行下方的“Episode”组件-----
class Episode{
constructor(title, link, author, description, published, enclosure, itunestags, mediatags, guid){
this.title = title.innerHTML
this.links = link.innerHTML
this.author = author.innerHTML
this.description = description.innerHTML
this.published = published.innerHTML
this.enc = enclosure.innerHTML
this.itunes = itunestags
this.media = mediatags
this.mp3url = mediatags[1].attributes[0].value // ACCURATE MP3 URL
this.id = guid.innerHTML // NOTE!!! This id is actually a text string url as a unique id in the rss document. not a good id, nor is it a good source for an accurate url string. Use "mp3url" property instead
// for accurate link to mp3 download, use this.media[1].attributes[0].value (0: url, 1: sample rate, 2:lang)
}
}
class Channel{
constructor(title, youtube_channel_url, description, language, copyright, image, itunes_tags, media_tags){
this.title = title.innerHTML
this.url = youtube_channel_url.innerHTML
this.description = description.innerHTML
this.lang = language.innerHTML
this.copyright = copyright.innerHTML
this.image = {
imgurl: image.children[0].innerHTML,
imgdesc: image.children[2].innerHTML,
width: image.children[4].innerHTML,
height: image.children[5].innerHTML
}
this.itunes = {
img: itunes_tags[0],
categories: [itunes_tags[1].innerHTML, itunes_tags[2].innerHTML, itunes_tags[3].innerHTML],
explicit: itunes_tags[4].innerHTML,
title: itunes_tags[5].innerHTML,
subtitle: itunes_tags[6].innerHTML,
summary: itunes_tags[7].innerHTML,
keywords: itunes_tags[8].innerHTML,
author: itunes_tags[9].innerHTML,
owner: itunes_tags[10].innerHTML,
link: itunes_tags[11].innerHTML
}
this.media = media_tags
}
}
// Make array of episodes, each with templated object notation data
let episodes = []
async function whenDataLoaded(){
// FOR PRODUCTION - COMMENT OUT FOR DEVELOPMENT MODE
let data = await fetch('https://krisdriver.com/feed/rssfeed.xml').then( res => {
// "data" is imported for development mode
// console.log(res)
return res.text()
})
// FOR PRODUCTION - COMMENT OUT FOR DEVELOPMENT MODE
// parse xml data and store
const parser = new DOMParser()
const xml = await parser.parseFromString(data, 'application/xml')
const getelements = await xml.getElementsByTagName('rss')
const channel = await getelements[0].getElementsByTagName('channel')[0]
// Create containers for episode data and channel data to create class objects out of
let channelData = await getChannelInfo(channel) // returns array of <channel> children until an <item> tag is traversed
let episodeData = await getEpisodeData(channel) // returns all item tags as html collection
for(let i of episodeData) {
episodes.push(new Episode(i.children[0], i.children[1], i.children[2], i.children[3], i.children[4], i.children[5], [i.children[6], i.children[7], i.children[8], i.children[9]], [i.children[10], i.children[11]], i.children[12]))
}
// Create an object with channel details in object legible notation
let i = await channelData // for less typing
const channelDetails = await new Channel(i[0], i[1], i[2], i[3], i[4], i[5], [ i[6], i[7], i[8], i[9], i[10], i[11], i[12], i[13], i[14], i[15], i[16], i[17] ], [ i[18], i[19], i[20], i[21], i[22], i[23], i[24], i[25], i[26], i[27], i[28], i[29], i[30], i[31], i[32], i[33] ] )
return [episodes, channelDetails]
}
function getEpisodeData(xml){
return xml.getElementsByTagName('item')
}
function getChannelInfo(xmlstream){
// console.log(xmlstream)
let kids = xmlstream.children
let result = []
for(let i = 0; i<kids.length-1; i++){
if(kids[i].tagName === 'item') return result // stop looping once we get to the first item tag, return completed list
else if(kids[i].nodeType === 1){
result.push(kids[i]) // add channel child elements which are not <item> tags to make a channel object with
}
}
}
let result = async function(){
let x = await whenDataLoaded();
return x
}
export default result()
下面正在解析的 RSS XML------------
<item>
<title>Ep.61: Public Good</title>
<link>https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg</link>
<author>[email protected] (Kristopher Driver and Jordan Roy)</author>
<description>Today Kris makes a case for government sponsored programs. This is not a narrow topic as allocation of resources is always a complicated mess of interests. Universities, corporations, the media, the general public, and those finding themselves at the bottom, all take part. Join us for this debate as we discuss what might work to lift up the less fortunate in our society so that we may all benefit. QUOTE: “The 25% of Spaniards who are presently without work simply don’t (by Milton’s presumption) want to work at the prevailing wage and are on vacation.” - Mark Blyth, Austerity: The History of a Dangerous Idea #FrivolousGravitas Links: Channel: https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg FB: https://www.facebook.com/Frivolous-Gravitas-Podcast-109356198202987/ Twitter: https://twitter.com/FrivolousGravi1 RSS: https://krisdriver.com/feed/rssfeed.xml If you like this kind of content and want to see more, be sure to like, share and subscribe to help keep this channel going. Use RSS url to subscribe to Frivolous Gravitas using your favourite podcast player to catch up on past episodes and listen any time you want. No commercials, no sponsors, no ads, just straight talk on demand and on the go. Original Music by Epistra </description>
<pubDate>Feb 18 2022 05:30:00 CST</pubDate>
<enclosure url="https://www.krisdriver.com/feed/podcast/ep61.mp3" type="audio/mpeg" length="187312271"/>
<itunes:author>Kristopher Driver and Jordan Roy</itunes:author>
<itunes:episodeType>full</itunes:episodeType>
<itunes:episode>61</itunes:episode>
<itunes:image>
<url>https://www.krisdriver.com/feed/rssitunesb.jpg</url>
<title>Frivolous Gravitas</title>
<link>https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg</link>
</itunes:image>
<media:title>Ep.61: Public Good</media:title>
<media:content url="https://www.krisdriver.com/feed/podcast/ep61.mp3" samplingrate="44.1" lang="en" type="audio/mpeg" expression="full"/>
<guid>http://www.krisdriver.com/feed/podcast/ep61.mp3</guid>
</item>
<item>
<title>Ep.60: Charity</title>
<link>https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg</link>
<author>[email protected] (Kristopher Driver and Jordan Roy)</author>
<description>It is hard to argue that charity is anything but good, but it is not always evident that our offerings are indeed worthwhile. Many who donate don't give much thought beyond the act itself, but charity is not so simple. It can be seen as a gamble, a waste, or a necessity depending on the point of view. We hope you will join us as we look at what makes a good, and bad, act of charity. QUOTE: "Whoever closes his ear to the cry of the poor will himself call out and not be answered." - Proverbs 21:13 #FrivolousGravitas Links: Channel: https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg FB: https://www.facebook.com/Frivolous-Gravitas-Podcast-109356198202987/ Twitter: https://twitter.com/FrivolousGravi1 RSS: https://krisdriver.com/feed/rssfeed.xml If you like this kind of content and want to see more, be sure to like, share and subscribe to help keep this channel going. Use RSS url to subscribe to Frivolous Gravitas using your favourite podcast player to catch up on past episodes and listen any time you want. No commercials, no sponsors, no ads, just straight talk on demand and on the go. Original Music by Epistra </description>
<pubDate>Feb 11 2022 12:30:00 CST</pubDate>
<enclosure url="https://www.krisdriver.com/feed/podcast/ep60.mp3" type="audio/mpeg" length="133276531"/>
<itunes:author>Kristopher Driver and Jordan Roy</itunes:author>
<itunes:episodeType>full</itunes:episodeType>
<itunes:episode>60</itunes:episode>
<itunes:image>
<url>https://www.krisdriver.com/feed/rssitunesb.jpg</url>
<title>Frivolous Gravitas</title>
<link>https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg</link>
</itunes:image>
<media:title>Ep.60: Charity</media:title>
<media:content url="https://www.krisdriver.com/feed/podcast/ep60.mp3" samplingrate="44.1" lang="en" type="audio/mpeg" expression="full"/>
<guid>http://www.krisdriver.com/feed/podcast/ep60.mp3</guid>
</item>
For some reason firefox and chrome don't seem to have the same sort method algorithms in their javascript engines. Is there a clear way to know why or how these are being processed differently from one another? It seems kind of strange to have to find out in testing that a simple array sort is causing bugs in other browsers when it should be a pretty straightforward comparison, no?
Here's the code I'm using: I collect an rss feed xml file, create a shallow copy to not be dealing with Symbols or whatever just in case, I just insert episodes with titles containing "Special" because I don't really care where they get inserted. Then, instead of creating date objects and doing a bunch of needless processing, since every episode title in the rss xml starts with the episode number like "Ep.25: Episode Name" I thought I could just parse the string and use the integer value between "Ep." and ":" to sort by integer instead of datetime objects.
For some reason Firefox doesn't give me the same results as Chrome and I can't understand how that would be different or wrong no matter what engine is processing the javascript.
See live example at https://krisdriver.com/fg
const EpisodeContainer = ()=>{
// random card background image if no specific index number is selected (select by map index)
const cardbg = ()=>{
let x = [bgselect]
return x[x.length-1]
}
// collect the rss feed info and start the async chain
async function loadingdata () {
return await rssdata
}
let data // collects results from async xml data collection
const epsperpage = 12 // PRODUCTION CONSIDERATION: consider allowing options for preloading, # per page, etc
const [datastate, setDataState] = useState(data)
const [epsLoaded, setEpsLoaded] = useState(false)
useEffect( ()=>{
loadingdata().then( res =>{
// eslint-disable-next-line react-hooks/exhaustive-deps
data = [...res]
let sortedEpisodes_byDate = [...data[0]] // create shallow copy, not reference
// start sorting the episodes by their data...
sortedEpisodes_byDate.sort( (x,y)=>{
// sorting episodes so part 1 and 2 are always in order
// exclude special episodes
if(!x.title.toUpperCase().includes('SPECIAL')){
// take the episode number from the title
let _temp = x.title.split(':') // take the "Ep.xx:" out of the title
let _temp2 = _temp[0].split('.') // take the number out of "Ep.xx"
let _temp3 = y.title.split(':')
let _temp4 = _temp3[0].split('.')
let [_x, _y] = [parseInt(_temp2[1]), parseInt(_temp4[1])] // compare integer values of ep numbers
if ( _x > _y) return 1 // sort
else return -1 // sort
}
else return -1 // just insert the specials
} )
let sorted = [...sortedEpisodes_byDate]
let _tmp = { eps: sorted.reverse(), channel: data[1] }
// return the sorted final output data object, without episodes being sectioned into pages
return _tmp
}).then( response=>{ // take final sorted data and start breaking it into sections for the DOM to render as pages...
if (datastate === undefined) {
// Organize episode info into pages
let numEpsDisplayedPerPage = epsperpage // referred to as 'x' in the comments of this scope
let numOfEps = response.eps.length
let episodePages = []
let pageloop = Math.ceil(numOfEps / numEpsDisplayedPerPage)
// for each page of x eps...
for(let i = 0; i < pageloop; i++){
let pageofepisodes = []
// for each of the x eps within page range...
for(let j = 0; j < numEpsDisplayedPerPage; j++ ){
// 'i*numEpsPerPage' is the index of Episode in the data array, the '+j' selects 1 through x on current page
pageofepisodes.push(response.eps[ (i*numEpsDisplayedPerPage) + j] )
}
episodePages.push([...pageofepisodes]) // make a shallow copy of the output array
}
// remove 'undefined' elements on the last page, if they exist
let len = episodePages.length-1
episodePages[len] = episodePages[len].filter( x => {
return x !== undefined
})
// finally, set the state to the data object which includes channel info, all episodes sorted, and paginated array
let tmp_obj = { ...response }
// remove time from publication date...
tmp_obj.eps.forEach( v => {
v.published = removeTimeFromPubDate(v.published).trim()
})
let tmp_ = { ...tmp_obj, pages: [...episodePages], sortselected: 1, currentPage: 0, buttonText: 'Newest First' }
// console.log(tmp_)
// ready, set state with data object sanitized
setDataState({ ...tmp_ })
// allow for useEffect to render contents
setEpsLoaded(true)
} // This all only runs on the first load, before the state is loaded. Data is parsed and split into pages
})
}, [])
// sanitize publish date to remove time and timezone from display cards next to episode titles
const removeTimeFromPubDate = (published) => published.split(':')[0].slice(0, -2)
"EPISODE" COMPONENT ABOVE THIS LINE--------
"data" imported into "Episode" component below this line-----
class Episode{
constructor(title, link, author, description, published, enclosure, itunestags, mediatags, guid){
this.title = title.innerHTML
this.links = link.innerHTML
this.author = author.innerHTML
this.description = description.innerHTML
this.published = published.innerHTML
this.enc = enclosure.innerHTML
this.itunes = itunestags
this.media = mediatags
this.mp3url = mediatags[1].attributes[0].value // ACCURATE MP3 URL
this.id = guid.innerHTML // NOTE!!! This id is actually a text string url as a unique id in the rss document. not a good id, nor is it a good source for an accurate url string. Use "mp3url" property instead
// for accurate link to mp3 download, use this.media[1].attributes[0].value (0: url, 1: sample rate, 2:lang)
}
}
class Channel{
constructor(title, youtube_channel_url, description, language, copyright, image, itunes_tags, media_tags){
this.title = title.innerHTML
this.url = youtube_channel_url.innerHTML
this.description = description.innerHTML
this.lang = language.innerHTML
this.copyright = copyright.innerHTML
this.image = {
imgurl: image.children[0].innerHTML,
imgdesc: image.children[2].innerHTML,
width: image.children[4].innerHTML,
height: image.children[5].innerHTML
}
this.itunes = {
img: itunes_tags[0],
categories: [itunes_tags[1].innerHTML, itunes_tags[2].innerHTML, itunes_tags[3].innerHTML],
explicit: itunes_tags[4].innerHTML,
title: itunes_tags[5].innerHTML,
subtitle: itunes_tags[6].innerHTML,
summary: itunes_tags[7].innerHTML,
keywords: itunes_tags[8].innerHTML,
author: itunes_tags[9].innerHTML,
owner: itunes_tags[10].innerHTML,
link: itunes_tags[11].innerHTML
}
this.media = media_tags
}
}
// Make array of episodes, each with templated object notation data
let episodes = []
async function whenDataLoaded(){
// FOR PRODUCTION - COMMENT OUT FOR DEVELOPMENT MODE
let data = await fetch('https://krisdriver.com/feed/rssfeed.xml').then( res => {
// "data" is imported for development mode
// console.log(res)
return res.text()
})
// FOR PRODUCTION - COMMENT OUT FOR DEVELOPMENT MODE
// parse xml data and store
const parser = new DOMParser()
const xml = await parser.parseFromString(data, 'application/xml')
const getelements = await xml.getElementsByTagName('rss')
const channel = await getelements[0].getElementsByTagName('channel')[0]
// Create containers for episode data and channel data to create class objects out of
let channelData = await getChannelInfo(channel) // returns array of <channel> children until an <item> tag is traversed
let episodeData = await getEpisodeData(channel) // returns all item tags as html collection
for(let i of episodeData) {
episodes.push(new Episode(i.children[0], i.children[1], i.children[2], i.children[3], i.children[4], i.children[5], [i.children[6], i.children[7], i.children[8], i.children[9]], [i.children[10], i.children[11]], i.children[12]))
}
// Create an object with channel details in object legible notation
let i = await channelData // for less typing
const channelDetails = await new Channel(i[0], i[1], i[2], i[3], i[4], i[5], [ i[6], i[7], i[8], i[9], i[10], i[11], i[12], i[13], i[14], i[15], i[16], i[17] ], [ i[18], i[19], i[20], i[21], i[22], i[23], i[24], i[25], i[26], i[27], i[28], i[29], i[30], i[31], i[32], i[33] ] )
return [episodes, channelDetails]
}
function getEpisodeData(xml){
return xml.getElementsByTagName('item')
}
function getChannelInfo(xmlstream){
// console.log(xmlstream)
let kids = xmlstream.children
let result = []
for(let i = 0; i<kids.length-1; i++){
if(kids[i].tagName === 'item') return result // stop looping once we get to the first item tag, return completed list
else if(kids[i].nodeType === 1){
result.push(kids[i]) // add channel child elements which are not <item> tags to make a channel object with
}
}
}
let result = async function(){
let x = await whenDataLoaded();
return x
}
export default result()
THE RSS XML BEING PARSED BELOW------------
<item>
<title>Ep.61: Public Good</title>
<link>https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg</link>
<author>[email protected] (Kristopher Driver and Jordan Roy)</author>
<description>Today Kris makes a case for government sponsored programs. This is not a narrow topic as allocation of resources is always a complicated mess of interests. Universities, corporations, the media, the general public, and those finding themselves at the bottom, all take part. Join us for this debate as we discuss what might work to lift up the less fortunate in our society so that we may all benefit. QUOTE: “The 25% of Spaniards who are presently without work simply don’t (by Milton’s presumption) want to work at the prevailing wage and are on vacation.” - Mark Blyth, Austerity: The History of a Dangerous Idea #FrivolousGravitas Links: Channel: https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg FB: https://www.facebook.com/Frivolous-Gravitas-Podcast-109356198202987/ Twitter: https://twitter.com/FrivolousGravi1 RSS: https://krisdriver.com/feed/rssfeed.xml If you like this kind of content and want to see more, be sure to like, share and subscribe to help keep this channel going. Use RSS url to subscribe to Frivolous Gravitas using your favourite podcast player to catch up on past episodes and listen any time you want. No commercials, no sponsors, no ads, just straight talk on demand and on the go. Original Music by Epistra </description>
<pubDate>Feb 18 2022 05:30:00 CST</pubDate>
<enclosure url="https://www.krisdriver.com/feed/podcast/ep61.mp3" type="audio/mpeg" length="187312271"/>
<itunes:author>Kristopher Driver and Jordan Roy</itunes:author>
<itunes:episodeType>full</itunes:episodeType>
<itunes:episode>61</itunes:episode>
<itunes:image>
<url>https://www.krisdriver.com/feed/rssitunesb.jpg</url>
<title>Frivolous Gravitas</title>
<link>https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg</link>
</itunes:image>
<media:title>Ep.61: Public Good</media:title>
<media:content url="https://www.krisdriver.com/feed/podcast/ep61.mp3" samplingrate="44.1" lang="en" type="audio/mpeg" expression="full"/>
<guid>http://www.krisdriver.com/feed/podcast/ep61.mp3</guid>
</item>
<item>
<title>Ep.60: Charity</title>
<link>https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg</link>
<author>[email protected] (Kristopher Driver and Jordan Roy)</author>
<description>It is hard to argue that charity is anything but good, but it is not always evident that our offerings are indeed worthwhile. Many who donate don't give much thought beyond the act itself, but charity is not so simple. It can be seen as a gamble, a waste, or a necessity depending on the point of view. We hope you will join us as we look at what makes a good, and bad, act of charity. QUOTE: "Whoever closes his ear to the cry of the poor will himself call out and not be answered." - Proverbs 21:13 #FrivolousGravitas Links: Channel: https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg FB: https://www.facebook.com/Frivolous-Gravitas-Podcast-109356198202987/ Twitter: https://twitter.com/FrivolousGravi1 RSS: https://krisdriver.com/feed/rssfeed.xml If you like this kind of content and want to see more, be sure to like, share and subscribe to help keep this channel going. Use RSS url to subscribe to Frivolous Gravitas using your favourite podcast player to catch up on past episodes and listen any time you want. No commercials, no sponsors, no ads, just straight talk on demand and on the go. Original Music by Epistra </description>
<pubDate>Feb 11 2022 12:30:00 CST</pubDate>
<enclosure url="https://www.krisdriver.com/feed/podcast/ep60.mp3" type="audio/mpeg" length="133276531"/>
<itunes:author>Kristopher Driver and Jordan Roy</itunes:author>
<itunes:episodeType>full</itunes:episodeType>
<itunes:episode>60</itunes:episode>
<itunes:image>
<url>https://www.krisdriver.com/feed/rssitunesb.jpg</url>
<title>Frivolous Gravitas</title>
<link>https://www.youtube.com/channel/UCb3cCrFqaHFBp2s7jgtJvFg</link>
</itunes:image>
<media:title>Ep.60: Charity</media:title>
<media:content url="https://www.krisdriver.com/feed/podcast/ep60.mp3" samplingrate="44.1" lang="en" type="audio/mpeg" expression="full"/>
<guid>http://www.krisdriver.com/feed/podcast/ep60.mp3</guid>
</item>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
自定义排序函数在传递任意两个数组值时,必须遵守不等式的反转属性。换句话说...
mySort( a, b ) == -mySort( b, a )
...否则会出现不一致的排序结果。根据我之前的评论,这似乎是
sortedEpisodes_byDate.sort( (x,y)...
算法的情况,该算法并不遵守数组值的每个组合的上述属性。举例说明...请注意,
mySort
不遵守 Reversal 属性,会返回不一致的数组排序。这是因为mySort
仅检查是否a.includes( 'SPECIAL' )
而不是b
,其方式与sortedEpisodes_byDate 类似
排序当前已编码。举个例子...mySort( 'abc', 'xyz-SPECIAL' )
返回 -1,因为'abc'
'xyz'
mySort( 'xyz-SPECIAL', 'abc' )
返回 -1 因为'xyz-SPECIAL'.includes( 'SPECIAL' )
所以现在,底层浏览器 JavaScript 引擎是否会将 'abc' 或 'xyz-SPECIAL' 视为较小的一个是一个问题......
底部行,我相信
sortedEpisodes_byDate.sort( (x,y)...
需要修复...A custom sort function, when passed any two array values, must adhere to the Reversal property of inequalities. In other words...
mySort( a, b ) == -mySort( b, a )
...otherwise inconsistent sort results will occur. Per my earlier comment, this appears to be the case with the
sortedEpisodes_byDate.sort( (x,y)...
algorithm, which does not adhere to the above property for every combination of array values. To exemplify...Note that
mySort
, not adhering to the Reversal property, returns inconsistent array sorts. This is becausemySort
only checks ifa.includes( 'SPECIAL' )
and notb
, in a similar fashion as thesortedEpisodes_byDate
sort is currently coded. Case in point...mySort( 'abc', 'xyz-SPECIAL' )
returns -1 because'abc' < 'xyz'
mySort( 'xyz-SPECIAL', 'abc' )
returns -1 because'xyz-SPECIAL'.includes( 'SPECIAL' )
So now it is a crapshoot as to whether the underlying browser Javascript engine is going to treat 'abc' or 'xyz-SPECIAL' as being the lesser of the other...
Bottom line, I believe the
sortedEpisodes_byDate.sort( (x,y)...
needs fixing...