Filter Array by Its Keys Using an Array of Allowed Keys

Filter array by its keys using an array of allowed keys

PHP 5.6 introduced a third parameter to array_filter(), flag, that you can set to ARRAY_FILTER_USE_KEY to filter by key instead of value:

$my_array = ['foo' => 1, 'hello' => 'world'];
$allowed = ['foo', 'bar'];
$filtered = array_filter(
$my_array,
function ($key) use ($allowed) {
// N.b. in_array() is notorious for being slow
return in_array($key, $allowed);
},
ARRAY_FILTER_USE_KEY
);

Since PHP 7.4 introduced arrow functions we can make this more succinct:

$my_array = ['foo' => 1, 'hello' => 'world'];
$allowed = ['foo', 'bar'];
$filtered = array_filter(
$my_array,
fn ($key) => in_array($key, $allowed),
ARRAY_FILTER_USE_KEY
);

Clearly this isn't as elegant as array_intersect_key($my_array, array_flip($allowed)), but it does offer the additional flexibility of performing an arbitrary test against the key, e.g. $allowed could contain regex patterns instead of plain strings.

You can also use ARRAY_FILTER_USE_BOTH to have both the value and the key passed to your filter function. Here's a contrived example based upon the first, but note that I'd not recommend encoding filtering rules using $allowed this way:

$my_array = ['foo' => 1, 'bar' => 'baz', 'hello' => 'wld'];
$allowed = ['foo' => true, 'bar' => true, 'hello' => 'world'];
$filtered = array_filter(
$my_array,
fn ($val, $key) => isset($allowed[$key]) && (
$allowed[$key] === true || $allowed[$key] === $val
),
ARRAY_FILTER_USE_BOTH
); // ['foo' => 1, 'bar' => 'baz']

Filter an array of objects with keys

you can do this:

array.filter((item)=>{return item.someKey==='valueYouWant'})

in your example you can do something like this:

const filtered=array.filter((item)=>{return item.categoryId<22})

How to filter array when object key value is in array

You can do it with Array.prototype.filter(),

var data = { records : [{ "empid": 1, "fname": "X", "lname": "Y" }, { "empid": 2, "fname": "A", "lname": "Y" }, { "empid": 3, "fname": "B", "lname": "Y" }, { "empid": 4, "fname": "C", "lname": "Y" }, { "empid": 5, "fname": "C", "lname": "Y" }] }
var empIds = [1,4,5]
var filteredArray = data.records.filter(function(itm){
return empIds.indexOf(itm.empid) > -1;
});

filteredArray = { records : filteredArray };

If​ the ​callBack​ returns a ​true​ value, then the ​itm​ passed to that particular callBack will be filtered out. You can read more about it here.​​​​​​

Filter object properties by key in ES6

If you have a list of allowed values, you can easily retain them in an object using:

const raw = {  item1: { key: 'sdfd', value:'sdfd' },  item2: { key: 'sdfd', value:'sdfd' },  item3: { key: 'sdfd', value:'sdfd' }};
const allowed = ['item1', 'item3'];
const filtered = Object.keys(raw) .filter(key => allowed.includes(key)) .reduce((obj, key) => { obj[key] = raw[key]; return obj; }, {});
console.log(filtered);

Use an array of keys to filter another array, keeping the order

Pretty simple

$data = [
'title' => 'loops and things',
'id' => '28fr2',
'link' => 'https://blah',
'itemid' => '28fr3',
'quantity' => 3,
//...
];
$product = [
'id',
'title',
'link'
];

$res = array_merge(array_fill_keys($product, null),array_intersect_key($data, array_flip($product)));
print_r($res);

Output

Array
(
[id] => 28fr2
[title] => loops and things
[link] => https://blah
)

Sandbox

How it works, The main trick here is array fill keys, and array merge. By using these we can create a "template" array. Because merging 2 arrays with the same keys merge in the order of the first array. So we can setup that first array to be the order of $product and then when we merge into that the "fake" values are replaced with the real values and the order is preserved.

If you wanted to you could also use the result of the array flip (or array fill keys), but then it would be 2 lines of code... :)

And of course we have to use something like array flip or array fill keys to change the values of $product into the keys we can use for array intersect key.

I used both array fill keys and array flip for variety, in this situation they are somewhat interchangeable. For example this is a bit more efficient:

$map = array_fill_keys($product, null);
$res = array_merge($map,array_intersect_key($data, $map));
print_r($res);

Sandbox

But then it takes 2 lines... I should mention array fill keys is preferred to array flip. It doesn't really matter because the array intersect key filters anything out not in map. But it's "in general" better because then the values of the map array are the same, whereas when using flip they are the numeric keys which can be a bit harder to work with for some situations (but not this one).

I almost for got you can functionize it like this

function ordered_array_intersect_key(array $data, array $map){
return array_merge(($map = array_fill_keys($map, null)),array_intersect_key($data, $map));
}

I took the liberty of naming it something sensible and by using assignment inline in array_merge you can have your cake and eat it too (reuse array_fill_keys and have 1 line). Something I just happened to think of when making a function out of it.

Sanbox

Enjoy!

UPDATE

Thanks to mosh442, for the idea. You can also use array_walk to build a new array like this:

$data = [
'title' => 'loops and things',
'id' => '28fr2',
'link' => 'https://blah',
'itemid' => '28fr3',
'quantity' => 3,
//...
];
$product = [
'id',
'title',
'link'
];

$new = [];

array_walk($product, function($v,$k,$data) use (&$new){$new[$v] = $data[$v];},$data);

print_r($new);

Output

Array
(
[id] => 28fr2
[title] => loops and things
[link] => https://blah
)

Sandox

I love questions like this, so much fun....

Filter array of objects on key from array of values JavaScript

Use map() to loop over the array of objects and create a new array with the result of filtering the object properties.

You should be using FilterArray.includes(), not key.includes().

const finalArray = [ { "cbsa_cde": "33460", "cbsa_nm": "Minneapolis-St. Paul-Bloomington, MN-WI", "countycode": "27053", "hh_50k_100k_201612": 71, "hh_50k_100k_201706": 86, "hh_50k_100k_201712": 60, "hh_50k_100k_201806": 37, "hh_50k_100k_201812": 49, "hh_50k_100k_201906": 35, "hh_50k_100k_201912": 38, "hh_50k_100k_202006": 46, "hh_50k_100k_202012": 58, "hh_100k_250k_201612": 120, "hh_100k_250k_201706": 121, "hh_100k_250k_201712": 153, "hh_100k_250k_201806": 126, "hh_100k_250k_201812": 126, "hh_100k_250k_201906": 125, "hh_100k_250k_201912": 120, "hh_100k_250k_202006": 99, "hh_100k_250k_202012": 84}, { "cbsa_cde": "33460", "cbsa_nm": "Minneapolis-St. Paul-Bloomington, MN-WI", "countycode": "27053","hh_50k_100k_201612": 20, "hh_50k_100k_201706": 33, "hh_50k_100k_201712": 22, "hh_50k_100k_201806": 41, "hh_50k_100k_201812": 52, "hh_50k_100k_201906": 45, "hh_50k_100k_201912": 40, "hh_50k_100k_202006": 41, "hh_50k_100k_202012": 50, "hh_100k_250k_201612": 99, "hh_100k_250k_201706": 108, "hh_100k_250k_201712": 130, "hh_100k_250k_201806": 84, "hh_100k_250k_201812": 90, "hh_100k_250k_201906": 97, "hh_100k_250k_201912": 89, "hh_100k_250k_202006": 95, "hh_100k_250k_202012": 87} ],
filterArray = [ "HH_50K_100K_201612", "HH_50K_100K_201706", "HH_100K_250K_201612", "HH_100K_250K_201706" ];

const result = finalArray.map(jsonData =>
Object.fromEntries(Object.entries(jsonData).filter(([key, value]) => filterArray.includes(key.toUpperCase()))));

console.log(result);

JavaScript How to filter array of objects by dynamic key?

Already Data

[
{item1: { key: 'sdfd', value:'sdfd' }},
{item2: { key: 'sdfd', value:'sdfd' }},
{item3: { key: 'sdfd', value:'sdfd' }}
]

Want Data

Want the data from target, when target is item1 :

[
{item1: { key: 'sdfd', value:'sdfd' }}
]

Current Code

let arr = [
{item1: { key: 'sdfd', value:'sdfd' }},
{item2: { key: 'sdfd', value:'sdfd' }},
{item3: { key: 'sdfd', value:'sdfd' }}
]

let target = 'item1'

// result array
let want = [
{item1: { key: 'sdfd', value:'sdfd' }},
]

Filtered object search using allowed keys and also a search value

const handleSearch = (searchValue) => {
if (searchValue !== '') {
const allowed = ['name', 'title'];
const list = props.search.list;

const filtered = list
.filter(obj =>
Object.keys(obj)
.some(k => allowed.includes(k))
)
.filter(obj =>
Object.values(obj)
.map(v => v.toLocaleLowerCase())
.some(v => v.includes(searchValue.toLowerCase()))
)

props.search.onChange(filtered)
} else {
props.search.onChange(props.search.list)
}
}

Example

Let's assume props as:

const props = {
search: {
list: [
{ name: "John", title: 'Owner' },
{ name: "Jane", title: 'Admin' },
{ name: "Reza", title: 'Owner' }
],
onChange: x => console.log(x)
},
}
handleSearch("own")

// [ { name: 'John', title: 'Owner' }, { name: 'Reza', title: 'Owner' } ]


handleSearch("jane")

// [ { name: 'Jane', title: 'Admin' } ]


handleSearch("something")

// []

how to filter a array of object by another object as key in JS?

You could map each key from filters and filter allData based on if filterTerm includes the item being searched, ignoring the filter if filterTerm is empty. Below example would also allow you to add more items to filterTerm if needed.

let allData = [
{title:"Adams",age:24,gender:"male"},
{title:"Baker",age:24,gender:"female"},
{title:"Clark",age:23,gender:"male"},
{title:"Davis",age:23,gender:"female"},
{title:"Ghosh",age:23,gender:"female"},
{title:"Adams",age:23,gender:"male"},
{title:"Irwin",age:25,gender:"male"}
]

let filters = {
title:{filterTerm:[]},
gender:{filterTerm:["male"]},
age:{filterTerm:[23]},
}

const getFilterRows = (rows, filters) => {
return rows.filter(row => (
Object.keys(filters)
.map(key => filters[key].filterTerm.length ? filters[key].filterTerm.includes(row[key]) : true)
.every(Boolean))
)
}

let filtered = getFilterRows(allData,filters)

console.log(filtered)

filter array of objects based on separate object keys, values

You could filter as follows: