通过2级深的键值查找对象

时间:2018-09-02 20:47:52

标签: javascript

https://jsfiddle.net/y1tq9563/29/

在下面,您可以单击shop-all并返回23,因为23是与查询相同的obj中的ID,shop-all ...但是查询时位于blade-servers之类的子节点中,id:应该返回26,但不会返回,因为.find不在children节点中查找。

我该如何重写

data.find( t => t.url.includes(query).id

,以便它也会出现在每个children节点中?

const data = [
  {
    "id": 23,
    "name": "Shop All",
    "url": "/shop-all/",
    "children": []
  },
  {
    "id": 18,
    "name": "Servers",
    "url": "/Servers/",
    "children": [
      {
        "id": 26,
        "name": "Blade Servers",
        "url": "/servers/blade-servers/"
      },
      {
        "id": 24,
        "name": "Rack Servers",
        "url": "/servers/rack-servers/"
      },
      {
        "id": 25,
        "name": "Tower Servers",
        "url": "/servers/tower-servers/"
      },
      {
        "id": 27,
        "name": "Workstations",
        "url": "/servers/workstations/"
      }
    ]
  }
];

$('.btn').click(e=> getID($(e.target).html()) );

function getID(query){
    /* reset */
    $('.results').html('');
    $('.err').html('');
    
   /* search for "query" */
    try {
      const result = data.find( t => t.url.includes(query) ).id; // whats wrong here?
      $('.results').html(`<div class="res-c">${result}</div>`);
    } catch(er) {
        $('.err').html(`<div class="err-c">${er}</div>`)
    }
}
body {
  background: #20262e;
  color: #fff;
  font-family: monospace;
  font-size: 25px;
}

.res-c {
   color: #6CE891;
   padding: 0.5em;
   margin: 0.5em;
   border: 2px solid #6CE891;
   border-radius: 5px;
}
.err-c {
   color: #ff4f68;
   padding: 0.5em;
   margin: 0.5em;
   border: 2px solid #ff4f68;
   border-radius: 5px;
}

.buttons{
  margin: 0.5em;
  margin-bottom: 1em;
}
.btn {
  font-size: 20px;
  border: 2px solid #fff;
  border-radius: 5px;
  padding: 0.5em;
}
.btn:hover {
  background: #fff;
  color: #20262e;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="buttons">
  <a class="btn">shop-all</a>
  <a class="btn">blade-servers</a>
</div>

<div class="results"></div>
<div class="err"></div>

  

也许我需要将.children:[i]映射到父级?

1 个答案:

答案 0 :(得分:2)

要找到 ID 父ID,您可以使用reduce检查父ID,然后.find匹配子(如果有)。仅凭一个.find就不够了:

const result = data.reduce((a, { url, children, id }) => {
  if (a) return a;
  if (url.includes(query)) return id;
  const foundChild = children.find(({ url }) => url.includes(query));
  if (foundChild) return foundChild.id;
}, null);

如果以后添加更多级别,最好使用递归函数。

const data = [
  {
    "id": 23,
    "name": "Shop All",
    "url": "/shop-all/",
    "children": []
  },
  {
    "id": 18,
    "name": "Servers",
    "url": "/Servers/",
    "children": [
      {
        "id": 26,
        "name": "Blade Servers",
        "url": "/servers/blade-servers/"
      },
      {
        "id": 24,
        "name": "Rack Servers",
        "url": "/servers/rack-servers/"
      },
      {
        "id": 25,
        "name": "Tower Servers",
        "url": "/servers/tower-servers/"
      },
      {
        "id": 27,
        "name": "Workstations",
        "url": "/servers/workstations/"
      }
    ]
  }
];

$('.btn').click(e=> getID($(e.target).html()) );

function getID(query){
    /* reset */
    $('.results').html('');
    $('.err').html('');
    
   /* search for "query" */
    try {
      const result = data.reduce((a, { url, children, id }) => {
        if (a) return a;
        if (url.includes(query)) return id;
        const foundChild = children.find(({ url }) => url.includes(query));
        if (foundChild) return foundChild.id;
      }, null)
      $('.results').html(`<div class="res-c">${result}</div>`);
    } catch(er) {
        $('.err').html(`<div class="err-c">${er}</div>`)
    }
}
body {
  background: #20262e;
  color: #fff;
  font-family: monospace;
  font-size: 25px;
}

.res-c {
   color: #6CE891;
   padding: 0.5em;
   margin: 0.5em;
   border: 2px solid #6CE891;
   border-radius: 5px;
}
.err-c {
   color: #ff4f68;
   padding: 0.5em;
   margin: 0.5em;
   border: 2px solid #ff4f68;
   border-radius: 5px;
}

.buttons{
  margin: 0.5em;
  margin-bottom: 1em;
}
.btn {
  font-size: 20px;
  border: 2px solid #fff;
  border-radius: 5px;
  padding: 0.5em;
}
.btn:hover {
  background: #fff;
  color: #20262e;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="buttons">
  <a class="btn">shop-all</a>
  <a class="btn">blade-servers</a>
</div>

<div class="results"></div>
<div class="err"></div>