简体   繁体   中英

From an array of objects, extract properties into multiple arrays (one per property)?

I have a JSON array of objects in JS that look something like this:

"data": [
   {"name": "abc", "location": "NY", "value": 1234, "potato": "tomato", "someOtherProp": "prop1"},
   {"name": "def", "location": "CA", ... etc}
   {etc ...},
]

I'm creating a UI for filtering down some of these fields and want to create an array for each attribute with all the given values in the data.

I know this is possible using something like this:

let result = objArray.map(a => a.name);

But using this strategy, I have to run map once for every property. Is there any way to only go through the array once but create a separate array for each? (Or is there a better way in general for creating filter options for a UI?)

To clarify, for the array above, I'd want an array for "names" (containing "abc" and "def"), an array for "locations" (containing NY, CA, etc.) an array for "potato"s and "someOtherProp".

I appreciate any help! Thanks

Loop through the array with .reduce() . In each iteration, loop through the keys of the object using Object.keys() , adding any unique values to an array of the same name.

This solution eliminates duplicate entries and works with any amount of properties.

 const data = [{name: "abc", location: "NY"},{name: "def", location: "CA"},{name: "xyz", location: "TX"},{name: "zyx", location: "TX"}]; const getFiltersFromData = (data) => { return data.reduce((out,obj) => { Object.keys(obj).forEach(k => { if (out[k] === undefined) out[k] = [obj[k]]; //Array doesn't exist yet - instantiate it else if (!out[k].includes(obj[k])) out[k].push(obj[k]); //Array exists and this value isn't in it - add the value to it }); return out; }, {}); }; const filters = getFiltersFromData(data); console.log(filters.name); console.log(filters.location);
 .as-console-wrapper, .as-console { height: 100% !important; max-height: 100% !important; top: 0; }

You could create the separate arrays from names, locations and values and then use map on the data array to push each attribute value to the arrays. You can do that vs. running map multiple times for each property:

var names = [];
var locations = [];
var values = [];

data.map((elt) => {
    names.push(elt.name);
    locations.push(elt.location);
    values.push(elt.value);
});

Try with Object.entries

You can get something like this:

const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM