第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

JavaScript 中高效的多對(duì)多關(guān)聯(lián)

JavaScript 中高效的多對(duì)多關(guān)聯(lián)

繁星淼淼 2022-05-26 14:44:05
在我的客戶(hù)端 JavaScript 應(yīng)用程序中,我需要一個(gè)多對(duì)多關(guān)聯(lián)機(jī)制來(lái)表示有向圖的邊:一個(gè)源可以有多個(gè)目標(biāo),一個(gè)目標(biāo)可以有多個(gè)源,例如:{source:n1, target:n2}{source:n1, target:n3}{source:n1, target:n4}{source:n2, target:n3}{source:n3, target:n4}我需要執(zhí)行四個(gè)操作:add_link(n1, n2); // add a link (unless present)has_link(n2, n4); // => false (no entry with source:n2 and target:n4)targets_of(n1);   // => [n2, n3, n4]sources_of(n4);   // => [n1, n3]另外兩個(gè)細(xì)節(jié):這種結(jié)構(gòu)會(huì)經(jīng)常被閱讀,但只是偶爾修改。如果這樣可以簡(jiǎn)化事情,“節(jié)點(diǎn)”可以是字符串鍵而不是對(duì)象。我可以將其實(shí)現(xiàn)為兩個(gè)映射:一個(gè)映射包含每個(gè)源的條目,其值是一組目標(biāo),另一個(gè)映射包含每個(gè)目標(biāo)的條目,其值是一組源。問(wèn)題:這是一個(gè)明智的做法嗎?JavaScript 領(lǐng)域中是否已經(jīng)存在一些數(shù)據(jù)結(jié)構(gòu)可以做到這一點(diǎn)?
查看完整描述

2 回答

?
一只甜甜圈

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超5個(gè)贊

不知道為什么 Fearless 沒(méi)有嵌入他的示例,但我冒昧地將其轉(zhuǎn)換為帶有 Mocha/Chai 單元測(cè)試的 ES6 類(lèi)。


正如其他人所提到的,有向圖應(yīng)該將其關(guān)聯(lián)(也稱(chēng)為邊)存儲(chǔ)在兩個(gè)單獨(dú)的集合中。


這使得查找變得微不足道。


class AssociationGraph {

  constructor() {

    this.sourceEdges = new Map();

    this.targetEdges = new Map();

  }


  /**

   * @brief Clear all associations

   */

  clear() {

    this.sourceEdges.clear();

    this.targetEdges.clear();

  }


  /**

   * @brief Return true if there is a link from source to target

   */

  hasLink(source, target) {

    let targets = this.sourceEdges.get(source);

    return targets != undefined && targets.has(target);

  }


  /**

   * @brief Create a link from source to target, unless one already exists.

   */

  addLink(source, target) {

    this._add(source, target, this.sourceEdges);

    this._add(target, source, this.targetEdges);

  }


  /**

   * @brief Return an iterator over all the targets of source.

   */

  targetsOf(source) {

    return this._of(source, this.sourceEdges);

  }


  /**

   * @brief Return an iterator over all the sources of target.

   */

  sourcesOf(target) {

    return this._of(target, this.targetEdges);

  }


  /**

   * @brief Return all unique nodes for all associations.

   */

  nodes() {

    return [...new Set([...this.sourceEdges.keys(), ...this.targetEdges.keys()])];

  }


  /**

   * @brief Return an iterator that generates edges e.g. {source: a, target:b}

   * for all links in the association.

   */

  edges() {

    let self = this;

    return (function*() {

      for (let [ srcKey, srcVal ] of self.sourceEdges.entries()) {

        for (let [ tarKey, tarVal ] of srcVal.entries()) {

          yield { source: srcKey, target: tarKey };

        }

      }

    })();

  }


  _add(a, b, store) {

    let set = store.get(a);

    if (set == undefined) {

      set = new Set();

      store.set(a, set);

    }

    set.add(b);

  }


  _of(a, map) {

    let b = map.get(a);

    if (b == undefined) {

      return new Set();

    } else {

      return b.keys();

    }

  }

}


// Construct a graph by adding associations

let graph = new AssociationGraph();

graph.addLink('n1', 'n2');

graph.addLink('n1', 'n3');

graph.addLink('n1', 'n4');

graph.addLink('n2', 'n3');

graph.addLink('n3', 'n4');


// Print the nodes

//for (let node of graph.nodes()) console.log(node);


// Print the edges

//for (let edge of graph.edges()) console.log(JSON.stringify(edge));


// Convenience function to transform a CSV string into an array

const strSet = (str) => str.trim().length > 0 ? str.split(/,/g) : [];


// Run a unit test

let assert = chai.assert,

    expect = chai.expect,

    should = chai.should;

mocha.setup("bdd");

chai.should();


describe('hasLink', () => {

  it('n1 ===> n2', () => graph.hasLink('n1', 'n2').should.equal(true));

  it('n2 =/=> n4', () => graph.hasLink('n2', 'n4').should.equal(false));

  it('n3 ===> n4', () => graph.hasLink('n3', 'n4').should.equal(true));

});


describe('targetsOf', () => {

  it('n1 : [n2, n3, n4]', () => expect(

    Array.from(graph.targetsOf('n1'))).to.have.members(strSet('n2,n3,n4')));

  it('n2 : [n3]', () => expect(

    Array.from(graph.targetsOf('n2'))).to.have.members(strSet('n3')));

  it('n3 : [n4]', () => expect(

    Array.from(graph.targetsOf('n3'))).to.have.members(strSet('n4')));

  it('n4 : []', () => expect(

    Array.from(graph.targetsOf('n4'))).to.have.members(strSet('')));

});


describe('sourcesOf', () => {

  it('n1 : []', () => expect(

    Array.from(graph.sourcesOf('n1'))).to.have.members(strSet('')));

  it('n2 : [n1]', () => expect(

    Array.from(graph.sourcesOf('n2'))).to.have.members(strSet('n1')));

  it('n3 : [n1, n2]', () => expect(

    Array.from(graph.sourcesOf('n3'))).to.have.members(strSet('n1,n2')));

  it('n4 : [n1, n3]', () => expect(

    Array.from(graph.sourcesOf('n4'))).to.have.members(strSet('n1,n3')));

});


describe('nodes', () => {

  it('graph.nodes()', () => expect( Array.from(graph.nodes())).to.have.members(strSet('n1,n2,n3,n4')));

});


mocha.run();

#mocha-report {

  font-family: monospace;

  font-size: smaller;

}

<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/7.1.1/mocha.min.js"></script><div id="mocha"></div>

<link href="https://cdnjs.cloudflare.com/ajax/libs/mocha/7.1.1/mocha.min.css" rel="stylesheet"/>


查看完整回答
反對(duì) 回復(fù) 2022-05-26
?
泛舟湖上清波郎朗

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超3個(gè)贊

正如@CertainPerformance 所提到的,兩個(gè)包含集合的地圖似乎可以解決問(wèn)題。產(chǎn)生的實(shí)施可用于:

https://gist.github.com/rdpoor/89ea64cb00107be368b2b69d7a89bb6c



查看完整回答
反對(duì) 回復(fù) 2022-05-26
  • 2 回答
  • 0 關(guān)注
  • 221 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)