2017-10-14 124 views
-1

我有這樣的對象數組如何在特定的字符串模式後搜索這個對象數組?如何使一個搜索功能,搜索一個數組

如果我輸入 'B' 的結果應該是 '彎' 和「本尼

如果我進入 '貝恩' 的結果應該是 '尼'

HTML

<form> 
    <input id="getCoins" type="text" name="getCoins" placeholder=""> 
</form> 

的JavaScript

var input = document.getElementById("getCoins"); 
var arr = [0:{name: 'bent', town: 'kansas'}1:{ name:'benny', town:'vegas'}] 
input .addEventListener("keyup", function(e){ 
    console.log(filterIt(arr, input.value)); 
} 

這是我從另一篇文章中嘗試過的,但是我無法使它工作?

function filterIt(arr, searchKey) { 
    return arr.filter(function (obj) { 
     return Object.keys(obj).some(function (key) { 
      return obj[key].includes(searchKey); 
     }) 
    }); 
} 

注:我只想要搜索的名稱,而不是鎮

+0

* 「我無法得到它的工作」 * - 它不會在所有的工作?它有效,但不正確? – kryger

+0

這是錯誤的:'var arr = [0:{name:'bent',town:'kansas'} 1:{name:'benny',town:'vegas'}]'。應該是:'var arr = {name:'bent',town:'kansas'}, {name:'benny',town:'vegas'} ];' –

回答

2

首先定義,決定給予單個項目過濾條件的功能。如果該項目應該是包括,此函數應該返回一個布爾值。

function match(inputValue, item) { /* .... */ } 

然後你就可以使用這個功能在Array.prototype.filter()功能,像這樣:

var matchingValues = arr.filter(match.bind(null, input.value)); 

由於match()函數有兩個參數,但filter()一次只能通過其回調一個項目,我們partially apply的匹配函數使用bind()input.valuematch()函數轉換爲僅會期望該項目的函數 。

這是一樣的做:

var matchingValues = arr.filter(function (item) { 
    return match(input.value, item); 
}); 

我發現代碼看起來更爲整潔,更容易理解,如果你使用的部分應用程序。

哦,其中一位評論者指出,OP只需要name部分。在這種情況下,簡單地鏈接一個.map()呼叫提取名稱:

var matchingNames = arr 
    .filter(function (item) { 
    return match(input.value, item); 
    }) 
    .map(function (item) { 
    return item.name; 
    }); 

編輯:你也應該修復陣列:

var arr = [{name: 'bent', town: 'kansas'}, { name:'benny', town:'vegas'}] 

我建議投資一些時間建立ESLint和集成到這你的編輯器,所以你的代碼看起來很像,並且至少沒有語法錯誤。

+0

這是因爲我正在檢索一個json對象,我推入這樣一個數組 'var coins = []; (jsonObj中的變量l){ coins.push(jsonObj [l]); }' –

+0

儘管如此,你的代碼片段會在現實生活中產生語法錯誤。 – hayavuk

0
function filterIt(arr, searchKey) { 
    return arr.filter(function (obj) { 
     return obj.name.search(searchKey) != -1; 
    }); 
} 
+1

他不想僅搜索「名稱」,他想搜索所有屬性。 – Thomas

0

可以使用forEach遍歷數組,然後for..in在每個對象進行迭代。在函數頂部聲明一個數組,然後將任何匹配推入數組並返回。

function findMatches(arr, searchString){ 
    const matches = []; 

    arr.forEach((obj) => { 
    for (const key in obj) { 
     if (obj[key].includes(searchString)){ 
     matches.push(obj[key]); 
     } 
    } 
    }); 

    return matches; 
} 

const arr = [ 
    {name: 'bent', town: 'kansas'}, 
    {name:'benny', town:'vegas'} 
]; 

console.log(findMatches(arr, "b")); 
// => ["bent", "benny"] 

console.log(findMatches(arr, "benn")); 
// => ["benny"] 
+0

您可以使用'filter()'並且一次完成所有操作,而不是使用'forEach()'和累加器數組。您可以使用此表達式來測試'obj'是否匹配:Object.keys (obj).some(function(key){return obj [key] .toLowerCase()。includes(searchString.toLowerCase())})' – hayavuk

+0

你確定嗎?這只是爲我返回兩個空陣列。 –

+0

這裏是我的意思小提琴:https://jsfiddle.net/y7k275eL/ – hayavuk

0

的更優化的解決方案是將預先提取的初始名稱/鎮字。然後,在每個keyup事件 - 在該字符串內搜索。

RegExp對象和String.match()功能的解決方案:

var input = document.getElementById("getCoins"), 
 
    arr = [{name: 'bent', town: 'kansas'},{ name:'benny', town:'vegas'}], 
 
    item_str = arr.map((o) => Object.values(o).join(' ')).join(' '); 
 

 
input.addEventListener("keyup", function(e){ 
 
    var pat = new RegExp('\\w*'+e.target.value+'\\w*', 'gi'); 
 
    console.log(item_str.match(pat)); 
 
});
<form> 
 
    <input id="getCoins" type="text" name="getCoins" placeholder=""> 
 
</form>