简体   繁体   English

如何在同一属性中过滤 object 数组?

[英]How Can I Filter Array of object in same property?

I have a Product Options "Color, Size, etc" And as we know user can select one thing from the option "selected just red color from Colors", in this time I ad the selected one the separate Array "All Option user selected" but the issue is the user can add duplicated options in the same filed "eg Color" So how can I solve this issue?我有一个产品选项“颜色、尺寸等”,而且我们知道用户可以 select 从“从颜色中选择红色”选项中的一件事,这次我将选择的一个广告添加到单独的数组“用户选择的所有选项”中但问题是用户可以在同一字段“例如颜色”中添加重复的选项那么我该如何解决这个问题? The final Thing should be: One thing from separate Option For Example最后的事情应该是:来自单独选项的一件事例如

SelectedOptions = [
      { name:"red",id:88,optionType:"Color"},
      { name:"XL",id:22,optionType:"Size"},
      ....
    ]

But What I go now但是我现在的 go

SelectedOptions = [
          { name:"red",id:88,optionType:"Color"},
          { name:"green",id:87,optionType:"Color"},
          { name:"XL",id:22,optionType:"Size"},
          { name:"M",id:22,optionType:"Size"},
          ....
        ];

I know that's because I push any selected one to the SelectedOptions Array, I'm trying to solve it by checking the optionType but I did not get any good idea我知道那是因为我将任何选定的一个推到 SelectedOptions 数组中,我试图通过检查optionType来解决它,但我没有得到任何好主意

选项

Code snippet代码片段

 const [selectedIndexColor, setSelectedIndexColor] = useState<
    number | undefined
  >();
  const [selectedIndexText, setSelectedIndexText] = useState<number | null>();
  const [selectedIndexImage, setSelectedIndexImage] = useState<number | null>();
  interface ManipulateValueOptionProp extends valueOptionProp {
    optionType: string;
  }
  const [allOptions, setAllOptions] = useState<ManipulateValueOptionProp[]>([]);

const renderValue = (value: valueOptionProp, type: string) => {
    const selectedColor = selectedIndexColor === value.id;
    const selectedText = selectedIndexText === value.id;
    const selectedImage = selectedIndexImage === value.id;
    switch (type) {
      case 'text': {
        return (
          <View
            style={[
              styles.selectedText,
              {backgroundColor: selectedText ? 'black' : 'transparent'},
            ]}>
            <Text
              style={{
                textAlign: 'center',
                color: selectedText ? 'white' : 'black',
                fontSize: 12,
              }}>
              {value.name_en}
            </Text>
          </View>
        );
      }
      case 'Color': {
        return (
          <>
            <View
              // @ts-ignore
              // eslint-disable-next-line react-native/no-inline-styles
              style={{
                width: 53,
                height: 53,
                backgroundColor: value.display_value,
              }}
            />
            {selectedColor ? (
              <View style={styles.selectedColor}>
                <CheckmarkIcon color="black" />
              </View>
            ) : null}
          </>
        );
      }
      case 'images': {
        return (
          <>
            <Image
              // @ts-ignore
              source={{uri: value.display_value}}
              // eslint-disable-next-line react-native/no-inline-styles
              style={{width: 53, height: 53, backgroundColor: '#0f4c7f'}}
            />
            {selectedImage ? (
              <View style={styles.selectedColor}>
                <CheckmarkIcon />
              </View>
            ) : null}
          </>
        );
      }
      default: {
        return null;
      }
    }
  };



{item.options.map((option) => {
        return (
          <View style={styles.optionsBox}>
            <Text style={styles.optionTxt}>{option.label_en}</Text>
            <View style={{flexDirection: 'row'}}>
              {option.values.map((value: valueOptionProp) => {
                return (
                  <ScalePressable
                    key={`${option.id}${value.id}`}
                    onPress={() => {
                      option.type === 'Color' &&
                        setSelectedIndexColor(value.id);
                      option.type === 'text' && setSelectedIndexText(value.id);
                      option.type === 'images' &&
                        setSelectedIndexImage(value.id);

                      if (
                        !allOptions.some(
                          (alreadyExist) => alreadyExist.id === value.id,
                        )
                      ) {
                        setAllOptions((options) => [
                          ...options,
                          {...value, optionType: option.type},
                        ]);
                      }
                    }}>
                    <View style={styles.values}>
                      {renderValue(value, option.type)}
                    </View>
                  </ScalePressable>
                );
              })}
            </View>
          </View>
        );
      })}

Here is one possible solution.这是一种可能的解决方案。 You may consider creating a new array by removing all options with the same option type as the new option and then adding the new option into the new array.您可以考虑通过删除与新选项具有相同选项类型的所有选项来创建新数组,然后将新选项添加到新数组中。

let selectedOptions = [
  { name: 'red', id: 88, optionType: 'Color' },
  { name: 'XL', id: 22, optionType: 'Size' },
];

let newOption = { name: 'green', id: 87, optionType: 'Color' };

selectedOptions = [
  ...selectedOptions.filter(
    option => option.optionType != newOption.optionType
  ),
  newOption,
];

Seems to me you just need to remove deselected options from allOptions array when the user presses that same filter option.在我看来,当用户按下相同的过滤器选项时,您只需要从allOptions数组中删除取消选择的选项。

onPress={() => {
  option.type === 'Color' && setSelectedIndexColor(value.id);
  option.type === 'text' && setSelectedIndexText(value.id);
  option.type === 'images' && setSelectedIndexImage(value.id);

  if (allOptions.some(option => option.type === value.type)) {
    setAllOptions(options => options.filter(option => option.type !== value.type));
  } else {
    setAllOptions((options) => [
      ...options,
      { ...value, optionType: option.type },
    ]);
  }
}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何过滤作为对象数组中对象属性的电子邮件域? - How can I filter an email domain that is a property of an object that is in an array of objects? 如何编写Angular ngFor管道来按对象属性过滤对象数组? - How can I write an Angular ngFor pipe to filter array of objects by object property? 如何使用数组值过滤对象? - How can I filter the Object with an Array values? 如何过滤包含子数组属性的数组? - How can I filter an array which contains a child array property? 如何使用对象属性过滤数组对象 - how to filter array object using object property 如何扩展此AngularJS过滤器以按对象属性按字母顺序排序? - How can I extend this AngularJS filter to sort alphabetically by object property? 我如何过滤数组并返回正确的属性? - How i can filter through an Array and return the correct property? 如何根据所包含属性的首字母过滤数组? - How can I filter an array based on the first letter of a contained property? 如何通过对象数组中的任何属性过滤数据? - How can I filter data by any property within an array of objects? 如何过滤对象数组并检查数组内是否有多个 object 在 Javascript 中具有相同的属性值? - How to filter array of objects and check if more than one object inside the array has the same property value in Javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM