简体   繁体   中英

Trying to find multiple objects from array when given multiple keys in an array

I'm going to be given an array of label text strings to match to values in an array. The array of objects is static but the array of text strings will be dynamic from user input. I want to know the best es6 way of setting this up using filter or map.

Here is the static array of objects:

const counts = [
    {label: '0-0', value: 1},
    {label: '0-1', value: 2},
    {label: '0-2', value: 3},
    {label: '1-0', value: 4},
    {label: '1-1', value: 5},
    {label: '1-2', value: 6},
    {label: '2-0', value: 7},
    {label: '2-1', value: 8},
    {label: '2-2', value: 9},
    {label: '3-0', value: 10},
    {label: '3-1', value: 11},
    {label: '3-2', value: 12},
];

This is an example of the array of keys I'll get:

Array [
  "0-2",
  "1-2",
  "2-0",
  "3-1"
]

So the results I want to get are an array with the values:

[3,6,7,11]

I have ways of doing this sloppily checking each value one by one, I'm just not sure what to use like filter, map, reduce, or find.

We can use filter and map function of JS for this.

 let test = [ "0-2", "1-2", "2-0", "3-1" ]; let counts = [{ label: '0-0', value: 1 }, { label: '0-1', value: 2 }, { label: '0-2', value: 3 }, { label: '1-0', value: 4 }, { label: '1-1', value: 5 }, { label: '1-2', value: 6 }, { label: '2-0', value: 7 }, { label: '2-1', value: 8 }, { label: '2-2', value: 9 }, { label: '3-0', value: 10 }, { label: '3-1', value: 11 }, { label: '3-2', value: 12 }, ]; let answer = counts.filter(item => ( test.includes(item.label) )).map(item => item.value) console.log(answer);

You can use array#reduce and add the matched label's value in that using array#find .

 const counts = [{ label: '0-0', value: 1 }, { label: '0-1', value: 2 }, { label: '0-2', value: 3 }, { label: '1-0', value: 4 }, { label: '1-1', value: 5 }, { label: '1-2', value: 6 }, { label: '2-0', value: 7 }, { label: '2-1', value: 8 }, { label: '2-2', value: 9 }, { label: '3-0', value: 10 }, { label: '3-1', value: 11 }, { label: '3-2', value: 12 }, ], input = [ "0-2", "1-2", "2-0", "3-1" ], output = input.reduce((arr, label) => { const matched = counts.find(o => o.label === label); if(matched) arr.push(matched.value); return arr; },[]); console.log(output);

You can create a Map which will act as a look-up-table ( lut ) for labels and their associated values. Using the Map you can then .map() your array of labels to be the value from the Map object.

By using this approach, you will only need to loop through your counts array once, and your labels array ( arr ) once, which will allow you to avoid " checking each value one by one ", providing you with a complexity of ~ O(n + k), rather than O(nk):

 const counts = [{label:"0-0",value:1},{label:"0-1",value:2},{label:"0-2",value:3},{label:"1-0",value:4},{label:"1-1",value:5},{label:"1-2",value:6},{label:"2-0",value:7},{label:"2-1",value:8},{label:"2-2",value:9},{label:"3-0",value:10},{label:"3-1",value:11},{label:"3-2",value:12}]; const arr = ["0-2", "1-2", "2-0", "3-1"]; const lut = new Map(counts.map(({label, value}) => [label, value])); const res = arr.map(label => lut.get(label)); console.log(res);

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