2016-12-05 15 views
1

連想配列を別のものにフィルタリングするにはどうすればいいですか?あなたはtry catchブロックせずに配列をfiter可能性が事前にJavascriptフィルタ配列と別の配列との連想配列

function filter (a,f) { 
    console.log (a) ; 
    console.log (f) ; 

    //Using f as filter, How to get only these rows fom a ? 
    //{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"}, 
    //{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"},     
} 

function test() { 
    var data = [{"XD_A":"XDL","XD_B_1":"38","XD_B_2":"PB"}, 
    {"XD_A":"XDR","XD_B_1":"51","XD_B_2":"PB"}, 
    {"XD_A":"XDL","XD_B_1":"58","XD_B_2":"PB"}, 
    {"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"}, 
    {"XD_A":"XDL","XD_B_1":"76","XD_B_2":"PB"}, 
    {"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"}] ; 
    var filters =[{"XD_A":"XDR"},{"XD_B_1":"38"}] ; 
    filter (data,filters) ; 
} 

おかげで、

よろしく

マッシモ

+1

は私たちにあなたがしようとしている何かを示して? – kukkuz

+0

var rf = _.dropRightWhile(data、filters);しかし成功なし。フィルタは動的に変更され、「増加」します –

答えて

2

let data = [{"XD_A":"XDL","XD_B_1":"38","XD_B_2":"PB"}, 
 
{"XD_A":"XDR","XD_B_1":"51","XD_B_2":"PB"}, 
 
{"XD_A":"XDL","XD_B_1":"58","XD_B_2":"PB"}, 
 
{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"One"}, 
 
{"XD_A":"XDL","XD_B_1":"76","XD_B_2":"PB"}, 
 
{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"Two"}], 
 
    filters =[{"XD_A":"XDR"},{"XD_B_1":"38"}]; 
 

 
console.info(filter(data, filters)); 
 

 
function filter(d, f){ 
 
    return data.filter(e => { 
 
    try{ 
 
     f.forEach(o => { 
 
     Object.keys(o).forEach(key => { 
 
      if(e[key] !== o[key]) throw new 1; 
 
     }); 
 
     }); 
 
     
 
     return true; 
 
    }catch(e){ 
 
     return false; 
 
    } 
 
    }); 
 
}

+0

これは完璧です! –

+1

@MassimoMagris、このウェブサイトで「ありがとうございます」と回答した場合は、回答の採択(回答の左側にチェックマーク)が表示されます。 – Other

0

function filter(data, filter) { 
 
    return data.filter(function (d) { 
 
     return filter.every(function (f) { 
 
      var k = Object.keys(f)[0]; 
 
      return d[k] === f[k]; 
 
     }); 
 
    }); 
 
} 
 

 

 
var data = [{ "XD_A": "XDL", "XD_B_1": "38", "XD_B_2": "PB" }, { "XD_A": "XDR", "XD_B_1": "51", "XD_B_2": "PB" }, { "XD_A": "XDL", "XD_B_1": "58", "XD_B_2": "PB" }, { "XD_A": "XDR", "XD_B_1": "38", "XD_B_2": "PB" }, { "XD_A": "XDL", "XD_B_1": "76", "XD_B_2": "PB" }, { "XD_A": "XDR", "XD_B_1": "38", "XD_B_2": "PB" }], 
 
    filters = [{ "XD_A": "XDR" }, { "XD_B_1": "38" }]; 
 

 
console.log(filter(data, filters));
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6

function filter(data, filter) { 
 
    return data.filter(d => filter.every(f => (k => d[k] === f[k])(Object.keys(f)[0]))); 
 
} 
 

 

 
var data = [{ "XD_A": "XDL", "XD_B_1": "38", "XD_B_2": "PB" }, { "XD_A": "XDR", "XD_B_1": "51", "XD_B_2": "PB" }, { "XD_A": "XDL", "XD_B_1": "58", "XD_B_2": "PB" }, { "XD_A": "XDR", "XD_B_1": "38", "XD_B_2": "PB" }, { "XD_A": "XDL", "XD_B_1": "76", "XD_B_2": "PB" }, { "XD_A": "XDR", "XD_B_1": "38", "XD_B_2": "PB" }], 
 
    filters = [{ "XD_A": "XDR" }, { "XD_B_1": "38" }]; 
 

 
console.log(filter(data, filters));
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

こんにちは、上記のソリューションは、データとフィルターがすべて同じ "フィールド"を持つ場合には完璧です。例えば、フィルタがフィルタ= [{"XD_A": "XDR"}、{"XC:" AA "}]の場合、"少なくともXD_Aの条件を満たしていてXCを持たない "フィールド"?この場合、今は0行が得られます。もう一度 –

+0

に感謝します。 –

+0

こんにちは、おかげで、上記の情報を用いて、溶液である:関数フィルタ(D、F){ リターンd.filter(E => { 試み{f.forEach(O => { Object.keys(O .forEach(key => { if((e [key]!== o [key])&&((e。hasOwnProperty(key))))throw new 1; }); }); がtrueを返します。 } catch(e){ falseを返します。 } }); } –

0

連想配列ソート、うーん?私はES6以外の方法でこれをやりたいと思っていました(私はその解決策に数分で着いたので、あなたはES6が大好きです)。あなたの正確な基準を自分の例から使いました。containsresultsstrict

はここで引数を使用して、いくつかの余分な出力結果が含まれる(ちょうど楽しみのためだけの場合は、)非ライブラリー、非ES6の方法です。

フィルターが増加/減少する必要がある場合にも拡張できます。 注:は、複数のオブジェクトプロパティを条件としてフィルタリングするのではなく、あなたが投稿したのとまったく同じようにフィルタリングしません: "連想配列"である複数の配列項目を使用します(ただし、これを変更することは可能です)。

これは私が最初に投稿したので、長年使用していました(申し訳ありません)とにかく、あなたのために働くことを願っています(FIDDLE HERE)、その他、マッシモ!

PS - それはがらくた/バギーだ場合、私はあなたがそれを修正するのに役立つ時間を見つけようとします。

/** 
* _filterStrict only gives back data if both filter criteria are satisfied 
* @param data {obj} 
*  filterList {arr} 
* @returns bool 
*/ 
var _filterStrict = function(data, filterList) { 
    var filterLength = filterList.length 
    // handy little truthy array 
    var strictMatchResults = [] 
    for (var i = 0; i < filterLength; ++i) { 
    for (var prop in filterList[i]) { 
     // we need to match both the property and value 
     if (data.hasOwnProperty(prop) && data[prop] === filterList[i][prop]) { 
     strictMatchResults.push(true) 
     } else { 
     // no truthy for you! YOU CAN'T HANDLE THE TRUTH! 
     continue; 
     } 
    } 
    } 
    return strictMatchResults.length === filterLength ? true : false 
} 

/** 
* _filterContains loose check; if data is found to be matching, it's a match. 
* @param prop {str} 
*  val {str} // !could be extended to allow more types! 
*  filterList {arr} 
* @returns bool 
*/ 
var _filterContains = function(prop, val, filterList) { 
    var filterLength = filterList.length 
    var found = [] 
    for (var i = 0; i < filterLength; ++i) { 
    // we need to match both the property and value 
    if (filterList[i].hasOwnProperty(prop) && filterList[i][prop] === val) { 
     return true 
    } else { 
     // "W-w-what? I have to go back to the expression, again? Ugh." 
     continue; 
    } 
    } 
} 

/** 
* _filterChoose detects which filter to use via filterMode and selects 
* the appropriate internal filter 
* @param dataToCheck {obj} 
*  filterList {arr} 
*  filterMode {str} 
* @returns arr 
*/ 
var _filterChoose = function(dataToCheck, filterList, filterMode) { 
    var dataMatchesFilter = null 
    var initObjFlag = false 
    var filterLength = filterList.length 

    // run in "strict search" mode 
    if (filterMode === 'strict') {   
    return _filterStrict(dataToCheck, filterList) ? dataToCheck : null 
    } 

    // loop through slice of data 
    for (var prop in dataToCheck) { 
    var val = dataToCheck[prop] 
    // check against filter criteria 
    if (_filterContains(prop, val, filterList)) { 
     // only create the object literal once 
     if (initObjFlag === false) { 
      initObjFlag = true 
     dataMatchesFilter = {} 
     } 
     // only return the found results from the array 
     if (filterMode === 'results') { 
     dataMatchesFilter[prop] = val 
     } 
     // return the whole value if the data matches anywhere in the array 
     if (filterMode === 'contains' || filterMode === '' || filterMode === undefined) { 
     dataMatchesFilter = dataToCheck 
     } 
    } 
    } 
    return dataMatchesFilter 
} 

/** 
* Filter "associative array" [{"str":"str"}] 
* - Searches one level deep. 
* - Filter Mode settings: 
*  * <contains|''|undefined> - loose search; returns whole object if even one *    match is found. This is the default. 
*  * results - returns results only (does not include any other original values) 
*  * strict - returns a match only if *all* filter criteria are met 
* 
* @param data {arr} 
*  filterList {arr} 
*  filterMode {str} - possible values: '', contains', 'results', 'strict' 
*/ 
var FilterAssoc = function(data, filterList, filterMode) { 
    // cache length for being nice to compiler guy/gal 
    var dataLength = data.length 
    var filteredArray = [] 
    // loop through array to access the object literals 
    for (var i = 0; i < dataLength; ++i) { 
    var filterRes = _filterChoose(data[i], filterList, filterMode) 
    // if results from our internal filter methods are NOT "null", 
    // then we need those results! 
    if (filterRes !== null) { 
     // build our results 
     filteredArray.push(filterRes) 
    } 
    } 
    return filteredArray 
} 

var filteredData = FilterAssoc(data, filters, 'strict') 

console.log(filteredData)