如何在Javascript中搜索对象数组中的特定值?

时间:2017-09-15 22:43:18

标签: javascript arrays object filter

我想要过滤/搜索的对象数组看起来像这样:

var array = [
 {  
    id: 62,
    title: "sometitle",
    text: „aaaaaaaaaaaaaaa“,
    keywords: ["other", "Party", "Shanghai"],
    read: false
},
{   
    id: 63,
    title: "othertitle",
    text: "bbbbbbbbbbbbbbbbbb",
    keywords: ["Party", "Shanghai", "Seo-Yeon"],
    read: false
},
{   
    id: 64,
    title: "againothertitle",
    text: "ccccccccccccccccccc",
    keywords: ["Chinesisch", "Alltag", "other"],
    read: false
}];

我想选择一个对象的随机值并过滤整个数组以查找共享此特定值的其他对象 - 当然除了当前对象。更确切地说,我想用一个“关键字”过滤数组。应该从数组中拼接当前对象。 同样在当前对象下面,我想显示按钮,每个按钮包含共享关键字的对象的标题。当用户点击其中一个按钮时,应该选择所显示的相应对象,再次从数组切片。应该随机选择其中一个选定对象的关键字来过滤数组的其余部分。 这就是实现应该是这样的:it looks right but doesnt behave right^^

这是html:

<body>
    <div id="container-fluid">
        <h2 id="title"></h2>
        <div id="output"></div> 
        <div id="button-container"></div>
     </div>      
    <script type="text/javascript" src="src/js/snu.js"></script>
    <script type="text/javascript" src="src/js/index.js"></script>
</body>

这就是JS:

var startKeywords = [];
var btnContainer = document.getElementById('button-container');
var title = document.getElementById('title');
var output = document.getElementById('output');
var container = document.getElementById('container-fluid');
var result = [];
var nextSnusButtons = [];
var button = [];
//select a random SNU
var randomIndex = Math.floor(Math.random() * snus.length); 

(function first() {
    //showing the first random scene
    var start = snus[randomIndex];
    title.innerHTML = start.title;
    title.id = start.id;
    output.innerHTML = start.text;
    start.read = true;
    cache.push(start);

    startKeywords = start.keywords;

    var randomStartKeyIndex = Math.floor(Math.random() * startKeywords.length); 
    var randomStartKey = startKeywords[randomStartKeyIndex];

    //create a filter
    function filterNextSet(val){
        var randomValueKeyIndex = Math.floor(Math.random() * val.keywords.length);
        var randomValueKey = val.keywords[randomValueKeyIndex];
        if (randomStartKey === val.keywords[0] || randomStartKey ===val.keywords[1] || randomStartKey === val.keywords[2] || randomStartKey === val.keywords[3] && randomStartKey.read === false) {
            return val
        }
    }

    //apply filter
    result = snus.filter(filterNextSet);
    var resultFirst = result[0];
    var resultLastIndex = result.length -1;
    var resultLast = result[resultLastIndex];
    var resultRandomIndex = Math.floor(Math.random() * result.length); 
    var resultRandom = result[resultRandomIndex];

    //generate HTML
    if(resultFirst.id  || resultRandom.id  || resultLast.id) {
        nextSnusButtons.push(resultFirst, resultRandom, resultLast);
        nextSnusButtons.forEach(function(nextSnu) {
            button = document.createElement('button');
            button.id = nextSnu.id;
            button.innerHTML = nextSnu.title;
            btnContainer.append(button);
        });
    }
})();

我一直使用普通的JavaScript来解决这个问题好几天但我只发现自己在Spghetti代码中。我觉得我一直在重复这些事情并且这不会结束。我将衷心感谢您的帮助!我应该使用React吗? 非常感谢你提前!

2 个答案:

答案 0 :(得分:0)

确定,

这是一个做第一部分(过滤数据)的简单例子。

在最后的示例中,我只显示每个组合的匹配项,在您的情况下,您可以使用随机数调用getForArrayItem。

&#13;
&#13;
var array = [
 {  
    id: 62,
    title: "sometitle",
    text: "aaaaaaaaaaaaaa",
    keywords: ["other", "Party", "Shanghai"],
    read: false
},
{   
    id: 63,
    title: "othertitle",
    text: "bbbbbbbbbbbbbbbbbb",
    keywords: ["Party", "Shanghai", "Seo-Yeon"],
    read: false
},
{   
    id: 64,
    title: "againothertitle",
    text: "ccccccccccccccccccc",
    keywords: ["Chinesisch", "Alltag", "other"],
    read: false
}];

function getForArrayItem(idx) {
  let 
    item = array[idx],
    iset = new Set(item.keywords);
  return array.filter((i) => {
    //first don't include self
    if (i === item) return false;
    //now see if any of the keyword exist in this
    return i.keywords.some(x => iset.has(x));
  });
}

array.forEach((item, ix) => {
  console.log('ITEM ' + item.id + ' = ' +
     getForArrayItem(ix).map((i)=>i.id).join(', '));
});
&#13;
&#13;
&#13;

这是一个仅使用ES5构造的片段。此外,我还没有使用任何forEach,有些,过滤..只是为了循环..

&#13;
&#13;
var array = [
 {  
    id: 62,
    title: "sometitle",
    text: "aaaaaaaaaaaaaa",
    keywords: ["other", "Party", "Shanghai"],
    read: false
},
{   
    id: 63,
    title: "othertitle",
    text: "bbbbbbbbbbbbbbbbbb",
    keywords: ["Party", "Shanghai", "Seo-Yeon"],
    read: false
},
{   
    id: 64,
    title: "againothertitle",
    text: "ccccccccccccccccccc",
    keywords: ["Chinesisch", "Alltag", "other"],
    read: false
}];

function getForArrayItem(idx) {
  var 
    item = array[idx],
    iset = {},
    ret = [],
    l;
  //first lets store a set of fast lookup keywords
  //we could use indexOf, but this should be faster
  for (l = 0; l < item.keywords.length; l++)
    iset[item.keywords[l]] = true;    
  //now loop through all arrays
  for (l = 0; l < array.length; l ++) {
    //lets not include our self
    if (l === idx) continue;
    var aitem = array[l], any = false;
    //now ltes see if any of keywords exist in our iset lookup
    for (var lc = 0; lc < aitem.keywords.length; lc++) {
      var keyword = aitem.keywords[lc];
      if (iset[keyword]) {
        ret.push(aitem);
        break;
      }
    }
    if (any) ret.push(item);
  }
  return ret;
}

for (var ix = 0; ix < array.length; ix ++) {
  var items = getForArrayItem(ix);
  var id_items = [];
  for (var ll = 0; ll < items.length; ll++) id_items.push(items[ll].id);
  console.log('ITEM ' + array[ix].id + ' = ' + id_items.join(', '));
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这是我的解决方案:

function selectRandomKeyword(obj) {
  const max = obj['keywords'].length;
  const random = Math.floor(Math.random() * max);
  return obj['keywords'][random];
}

function findObjsWithKeyword(array, keyword) {
  const foundArray = [];
  array.forEach(obj => {
    if (obj['keywords'].includes(keyword)) {
      foundArray.push(obj);
    }
  });
  return foundArray;
}

const selectedObj = (array[0]);

const keyword = selectRandomKeyword(selectedObj);

const newObjs = findObjsWithKeyword(array, keyword);

所以newObjs会让您的新数组只包含随机选择的匹配关键字。如果你想删除selectedObj:

var index = newObjs.indexOf(selectedObj);

newObjs.splice(index, 1);

newObjs;