Javascript JS:Don';t在条件下为映射添加值

Javascript JS:Don';t在条件下为映射添加值,javascript,arrays,Javascript,Arrays,我有一个需要转换为数组的对象。这就是目标: const dogCounts: { maltese: 4, poodle: 2, labrador: 10, corso: 0 } 我通过道具将它发送到一个组件,我有一个useMemo钩子将它转换成这样的结构:[[maltese,4],[poodle,2],…] const formatDogCounts = useMemo(() => { const z = Object.keys(dogCounts

我有一个需要转换为数组的对象。这就是目标:

const dogCounts: {
    maltese: 4,
    poodle: 2,
    labrador: 10,
    corso: 0
}
我通过道具将它发送到一个组件,我有一个useMemo钩子将它转换成这样的结构:
[[maltese,4],[poodle,2],…]

const formatDogCounts = useMemo(() => {
    const z = Object.keys(dogCounts || {})?.map(i => {
        if (dogCounts[i] === 0) return; // Don't add it to map and skip it

        return [i, dogCounts[i]]
    })
}, [dogCounts])
当数字为零时,我不想将其添加到formatDogCounts变量中。我上面说的不符合eslints的规则<代码>箭头函数不应返回值。eslintconsistent返回值


此外,我还将{}放在object.keys中,以便在计数尚未加载的情况下,是否有更干净的方法来检查空值?

您正在尝试使用
映射进行过滤,这是不可能的。映射将返回与您输入的值相同的值量。您可以执行
foreach
或将
map
filter
组合以获得预期结果

Foreach

const z = []

Object.keys(dogCounts).forEach((key) => {
  if(dogCounts[key]) {
    // if the value is truthy push the structure to the array. 
    z.push([key, dogCounts[key]]); 
  }
}
映射/筛选

const z = Object.keys(dogCount)
  .map((key) => [key, dogCount[key]) // map to restructure object.keys
  .filter(([key, value]) => value); // filter to remove falsey values (0, null, undefined) 

您正在尝试使用
映射进行筛选,这是不可能的。映射将返回与您输入的值相同的值量。您可以执行
foreach
或将
map
filter
组合以获得预期结果

Foreach

const z = []

Object.keys(dogCounts).forEach((key) => {
  if(dogCounts[key]) {
    // if the value is truthy push the structure to the array. 
    z.push([key, dogCounts[key]]); 
  }
}
映射/筛选

const z = Object.keys(dogCount)
  .map((key) => [key, dogCount[key]) // map to restructure object.keys
  .filter(([key, value]) => value); // filter to remove falsey values (0, null, undefined) 

map
不会过滤掉值;做一个简单的
返回map
中的code>使结果数组中的相应条目
未定义
。如果你想这样做,你需要先过滤,或者用另一种方法构建数组(比如一个简单的循环)

以下是
过滤器
方法:

const formatDogCounts = useMemo(() => {
    const z = Object.keys(dogCounts || {})?
                .filter(name => dogCounts[name] !== 0)
                .map(name => [name, dogCounts[i]]);
}, [dogCounts]);
请注意,
Object.entries
提供了所需的
[name,value]
对,因此您可以避免使用
map
,并且没有理由将条件链接操作符作为
对象.key
对象。entries
会返回
未定义的
null

const formatDogCounts = useMemo(() => {
    const z = Object.entries(dogCounts || {})
                .filter(([, value]) => value !== 0);
}, [dogCounts]);
请注意
[,value]
解构模式中
值之前的
,因此我们获取的是第二个数组项(值),而不是第一个数组项(名称)

当没有
狗计数时,我们还可以完全避免调用
Object.entries
filter

const formatDogCounts = useMemo(() => {
    const z = dogCounts
        ? Object.entries(dogCounts).filter(([, value]) => value !== 0)
        : [];
}, [dogCounts]);

你在评论中说:


这个解决方案对我来说非常有效!现在有没有办法返回一个对象,而不是一个总狗数的数组,然后返回一个项目数组?例如:formatDogCounts:{totalDogs:30,items:[…]}

当然。如果只有合理数量的狗(少于几十万只),我会在最后单独做一次手术:

const formatDogCounts = useMemo(() => {
    const items = dogCounts
        ? Object.entries(dogCounts).filter(([, value]) => value !== 0)
        : [];
    return {
        totalDogs: items.reduce((sum, [, value]) => sum + value, 0),
        items,
    };
}, [dogCounts]);
(我会做的,只有直接求和才能临时使用
reduce
,即使这样,我也不太在乎。)

或者,您可以使您的
过滤器
回调稍微不纯,并在运行时对其进行计数:

const formatDogCounts = useMemo(() => {
    let totalDogs = 0;
    const items = dogCounts
        ? Object.entries(dogCounts).filter(([, value]) => {
            totalDogs += value;
            return value !== 0;
        })
        : [];
    return {
        totalDogs,
        items,
    };
}, [dogCounts]);

map
不会过滤掉值;做一个简单的
返回map
中的code>使结果数组中的相应条目
未定义
。如果你想这样做,你需要先过滤,或者用另一种方法构建数组(比如一个简单的循环)

以下是
过滤器
方法:

const formatDogCounts = useMemo(() => {
    const z = Object.keys(dogCounts || {})?
                .filter(name => dogCounts[name] !== 0)
                .map(name => [name, dogCounts[i]]);
}, [dogCounts]);
请注意,
Object.entries
提供了所需的
[name,value]
对,因此您可以避免使用
map
,并且没有理由将条件链接操作符作为
对象.key
对象。entries
会返回
未定义的
null

const formatDogCounts = useMemo(() => {
    const z = Object.entries(dogCounts || {})
                .filter(([, value]) => value !== 0);
}, [dogCounts]);
请注意
[,value]
解构模式中
值之前的
,因此我们获取的是第二个数组项(值),而不是第一个数组项(名称)

当没有
狗计数时,我们还可以完全避免调用
Object.entries
filter

const formatDogCounts = useMemo(() => {
    const z = dogCounts
        ? Object.entries(dogCounts).filter(([, value]) => value !== 0)
        : [];
}, [dogCounts]);

你在评论中说:


这个解决方案对我来说非常有效!现在有没有办法返回一个对象,而不是一个总狗数的数组,然后返回一个项目数组?例如:formatDogCounts:{totalDogs:30,items:[…]}

当然。如果只有合理数量的狗(少于几十万只),我会在最后单独做一次手术:

const formatDogCounts = useMemo(() => {
    const items = dogCounts
        ? Object.entries(dogCounts).filter(([, value]) => value !== 0)
        : [];
    return {
        totalDogs: items.reduce((sum, [, value]) => sum + value, 0),
        items,
    };
}, [dogCounts]);
(我会做的,只有直接求和才能临时使用
reduce
,即使这样,我也不太在乎。)

或者,您可以使您的
过滤器
回调稍微不纯,并在运行时对其进行计数:

const formatDogCounts = useMemo(() => {
    let totalDogs = 0;
    const items = dogCounts
        ? Object.entries(dogCounts).filter(([, value]) => {
            totalDogs += value;
            return value !== 0;
        })
        : [];
    return {
        totalDogs,
        items,
    };
}, [dogCounts]);

如果要同时执行
映射
筛选
操作,可以使用,返回空数组以跳过元素

const formatDogCounts = useMemo(() => {
    const z = Object.keys(dogCounts || {})?.flatMap(i => {
      if(dogCounts[i] === 0) return []; // Dont add it to map and skip it

      return [[i, dogCounts[i]]];
    })
  }, [dogCounts])

如果要同时执行
映射
筛选
操作,可以使用,返回空数组以跳过元素

const formatDogCounts = useMemo(() => {
    const z = Object.keys(dogCounts || {})?.flatMap(i => {
      if(dogCounts[i] === 0) return []; // Dont add it to map and skip it

      return [[i, dogCounts[i]]];
    })
  }, [dogCounts])

map
包含每个项目,但返回值为。使用
filter
而不是
map
map
包含每个项目,但返回值是。使用
filter
而不是
map
。条目解决方案对我来说非常有效!现在有没有办法返回一个对象,而不是一个总狗数的数组,然后返回一个项目数组?例如:formatDogCounts:{totalDogs:30,items:[…]}@ousmane784-当然,我已经展示过这样做。快乐编码!哦,就速度而言,过滤器回调会更快吗?因为reduce方法需要再次循环通过数组?@ousmane784-可能,但你必须处理数组中的数十万个条目(或更多)。条目解决方案对我来说非常有效!现在有没有办法返回一个对象,而不是一个总狗数的数组,然后返回一个项目数组?例如:formatDogCounts:{totalDogs:30,items:[…]}@ousmane784-当然,我已经展示过这样做。快乐编码!嗯,就速度而言,过滤器回调会更快吗