简体   繁体   中英

How to filter out key-value pairs with typeof string

I'm trying map through Object keys and need to remove any key-value pair that has a value with a type of string. This is the list I'm mapping through

base: Object { 1: "#F3F5F7", 2: "#E0E6EB", 3: "#C5CFD8", … }
color1: "#E0E6EB"
color2: "#697886"
neutral: Object [ "#FFFFFF", "#000000" ]
secondaryColor: "purple",
primaryColor: "red",

I need to keep base and neutral and discard everything else before continuing mapping through the items. Still don't completely understand reduce . Where/how would I introduce a reduce or filter to this to get my desired result?

return Object.keys(colors).map((color) => {
  return (
    <span key={color}>{color}</span>
  );
});

You can map over the list itself (not the object) and transform your objects, removing what you don't want:

// Using destructuring on the parameter and returning a new object.
objectList.map(({ base, neutral }) => ({ base, neutral }))

for example like this, transforming object to pairs of key and value, filtering non-string pairs and then convert it to strings

Object.entries(colors)
  .filter(([_, color]) => typeof color !== "string")
  .map(([key, color]) => <span key={key}>{color}</span>)

Use Object.entries to get both key and value when iterating, then filter values that are not strings using filter , and then iterate again and render each filtered color. Use flat to flatten the result.

return Object.entries(colors)
  .filter(([key, value]) => typeof value !== 'string')
  .map(([key, value]) => {
    return Object.entries(value).map(([key, color]) => {
      return (<span key={color}>{color}</span>);
    });
  }).flat();

If I understand right you want to remove anything from your object that is type "string". You could use reduce for that, yes. The example of reduce from MDN shows the basic behavior:

const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10
// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15

You're going to iterate over an array (in your case the object keys). You'll then run each key through a function, passing both an accumulator and the current value of the loop. Your processing will return an updated value to the accumulator.

const keys = Object.keys(colors);
const reducer = (accumulator, currentValue) => {
  if (typeof Object[currentValue] !== 'string') {
    accumulator[currentValue] = Object[currentValue];
  }
  return accumulator;
}
keys.reduce(reducer, {});

That last empty object passed to reduce is the initial value of the accumulator. We start with an empty object because you'll be gradually adding values back into it if they aren't of type string.

Instead of discarding before mapping, you can ignore irrelevant keys during mapping itself!

let colors = {
    base: { 1: "#F3F5F7", 2: "#E0E6EB", 3: "#C5CFD8"},
    color1: "#E0E6EB",
    color2: "#697886",
    neutral: [ "#FFFFFF", "#000000" ],
    secondaryColor: "purple",
    primaryColor: "red"
}
console.log("Using map")
Object.keys(colors).map((key)=>{
    if(typeof(colors[key])!=='string')
        console.log(key,colors[key]) // Do whatever you want with these relevant keys
})
console.log("Using filter")
let result = Object.keys(colors).filter((key)=>{
    return typeof(colors[key])!=='string'
})
console.log(result) // Do whatever you want with these relevant keys

Output

Using map
base { '1': '#F3F5F7', '2': '#E0E6EB', '3': '#C5CFD8' }
neutral [ '#FFFFFF', '#000000' ]
Using filter
[ 'base', 'neutral' ]

You can use Object.keys() and filter() :

 const obj = { base: { 1: "#F3F5F7", 2: "#E0E6EB", 3: "#C5CFD8"}, color1: "#E0E6EB", color2: "#697886", neutral: [ "#FFFFFF", "#000000" ], secondaryColor: "purple", primaryColor: "red", } let newObj = {}; Object.keys(obj).filter(key => typeof obj[key] !== 'string').forEach(key => { newObj[key] = obj[key]; }) console.log(newObj)

Give it a try with reduce, this will filter and create a new Object I hope this helps:



const Obj = {
  base:  { 1: "#F3F5F7", 2: "#E0E6EB", 3: "#C5CFD8"},
  color1: "#E0E6EB",
  color2: "#697886",
  neutral:  [ "#FFFFFF", "#000000" ],
  secondaryColor: "purple",
  primaryColor: "red"
}

const notTypeString = Object.keys(Obj).reduce(((acc, curr) => {
  if(typeof Obj[curr] !== 'string') {
    const filteresObj = Obj[curr]
    return {...acc, [curr]: filteresObj}
  }

  return acc;
}), {});

console.log(notTypeString)


Use .map for create a new objetList or on the same list

const newList = objectList.map(val => ({
  base: val['base'],
  neutral: val['neutral']
}))
console.log(newList)

output

{
  base: Object { 1: "#F3F5F7", 2: "#E0E6EB", 3: "#C5CFD8", … },
  neutral: Object [ "#FFFFFF", "#000000" ]
}

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