js树结构--过滤数据(查找,筛选)

Java递归实现树结构遍历展示以及条件筛选 阅读详情

树结构过滤(查找)数据,父级一起带出来。

搜索到的结果 

树形结构数据的高效过滤与父级关联方案 

问题场景:树形数据的智能搜索

在实际开发中,我们经常需要处理树形结构数据的搜索过滤,并且要求能够同时返回匹配节点及其所有父级节点。这种需求在文件系统、组织架构、分类目录等场景中十分常见。本文将深入分析一个树形数据过滤方案,并提供多种优化思路。

基础实现方案分析

直接上代码。。。。

/**
   * @author 过滤数据
   * @param {*} value
   * @param {*} arr
   * @return {*} []
   */
  const TreeDataList = (value:any = '', arr:any) => {
    if (!arr) {
      return []
    }
    let newList:any[] = [];
    arr.forEach((item:any) => {
      if (item.title1.indexOf(value) > -1) {
        const Children = TreeDataList(value, item.children);
        const obj = {
          ...item,
          children: Children
        }
        console.log(item,obj,Children);
        newList.push(obj);
      } else {
        if (item.children && item.children.length > 0) {
          const Children = TreeDataList(value, item.children);
          const obj = {
            ...item,
            children: Children
          };
          if (Children && Children.length > 0) {
            newList.push(obj);
          }
        }
      }
    });
    return newList;
  };

当前实现特点:

  1. 递归遍历树形结构

  2. 匹配包含关键词的节点(title1)

  3. 自动保留有效子节点的父级

  4. 返回保持原有结构的新树

优化方案一:性能提升版

const filterTree = (keyword = '', treeData = []) => {
  if (!treeData.length) return [];
  
  return treeData.reduce((result, node) => {
    // 检查当前节点是否匹配
    const isMatch = node.title1.includes(keyword);
    
    // 递归处理子节点
    const children = filterTree(keyword, node.children || []);
    
    // 如果当前节点匹配或有匹配的子节点,则保留该节点
    if (isMatch || children.length) {
      result.push({
        ...node,
        children: children.length ? children : undefined
      });
    }
    
    return result;
  }, []);
};

优化点:

  1. 使用reduce替代forEach,减少中间变量

  2. 简化条件判断逻辑

  3. 使用includes替代indexOf,语义更清晰

  4. 空子节点设为undefined而非空数组,减少内存占用

优化方案二:支持多字段搜索

const filterTreeAdvanced = (
  keyword = '', 
  treeData = [],
  searchFields = ['title1', 'title2', 'code']
) => {
  return treeData.filter(node => {
    // 检查当前节点是否匹配任意搜索字段
    const isNodeMatch = searchFields.some(
      field => node[field]?.toString().includes(keyword)
    );
    
    // 递归处理子节点
    const matchedChildren = filterTreeAdvanced(
      keyword, 
      node.children || [], 
      searchFields
    );
    
    // 保留当前节点条件
    return isNodeMatch || matchedChildren.length;
  }).map(node => ({
    ...node,
    children: filterTreeAdvanced(keyword, node.children || [], searchFields)
  }));
};

增强功能:

  1. 支持多个字段的搜索

  2. 自动处理字段值为非字符串的情况

  3. 更简洁的函数式编程风格

优化方案三:非递归实现(避免栈溢出)

const filterTreeIterative = (keyword, treeData) => {
  const stack = [...treeData.map(node => ({ node, parent: null }))];
  const result = [];
  
  while (stack.length) {
    const { node, parent } = stack.pop();
    
    const isMatch = node.title1.includes(keyword);
    let shouldKeep = isMatch;
    
    // 处理子节点
    const children = (node.children || []).map(child => ({
      node: child,
      parent: node
    }));
    
    // 如果有匹配的子节点,当前节点也需要保留
    const hasMatchingChildren = children.some(
      ({ node: child }) => child.title1.includes(keyword)
    );
    shouldKeep = shouldKeep || hasMatchingChildren;
    
    if (shouldKeep) {
      const newNode = { ...node, children: [] };
      if (parent) {
        parent.children.push(newNode);
      } else {
        result.push(newNode);
      }
    }
    
    // 将子节点压入栈中
    stack.push(...children);
  }
  
  return result;
};

优势:

  1. 使用迭代替代递归,避免栈溢出风险

  2. 显式处理父子关系,逻辑更清晰

  3. 适合处理深度很大的树结构

性能对比

方案优点缺点适用场景
基础递归实现简单性能一般,可能栈溢出小规模数据
优化递归代码简洁仍存在递归风险中等规模数据
多字段搜索功能强大性能开销稍大需要多字段搜索
迭代实现无栈溢出风险代码较复杂超深树结构

最佳实践建议

  1. 数据规模考虑:

    • <1000节点:递归方案即可

    • 1000节点:考虑迭代实现

  2. 搜索体验优化:

    • 添加防抖处理(300ms)

    • 支持模糊搜索(考虑正则表达式)

    • 高亮显示匹配内容

总结

树形数据的过滤搜索是一个常见但具有挑战性的需求。本文从基础实现出发,逐步介绍了多种优化方案,每种方案都有其适用场景。在实际项目中,建议:

  1. 根据数据规模选择合适算法

  2. 考虑添加缓存机制优化重复搜索

  3. 做好错误处理和性能监控

  4. 在用户体验和性能之间取得平衡

希望这些方案能为你的树形数据搜索需求提供有价值的参考!

"敏感词过滤"了解一下? "敏感词过滤"了解一下?引言字符串匹配?暴力匹配?KMP?字典树 引言 如果说项目中有用户输入的内容,那么大家肯定会需要敏感词过滤,那么大家项目中的敏感词都是怎么过滤的呢? 例如这里有这些敏感词 "java",“python”,“go”,“js”,"c++" ,那么怎么从下面的句子中过滤出这个敏感词呢? "I want to learn ja java, python, js, c++.ja" 字... 阅读详情

相关推荐

【Dv2Admin】数据单字段多选进行数据过滤

通过本文的介绍,可以看到如何在Django-vue-admin框架中实现多选过滤功能。通过自定义过滤方法和前后端的协作,系统能够处理复杂的多条件数据筛选需求。这不仅提升了用户体验,也大大提高了数据检索的效率。在教育管理系统中,这种多选搜索功能非常有价值,因为它允许用户根据多种条件快速筛选学生信息。这种灵活的过滤方式不仅适用于教育系统,也可广泛应用于其他需要处理大量数据的领域。

Mr数据杨 1208

树型数据筛选实现方案-Java

1、人员根据身份的不同对部门有不同的权限。1、根据条件,标注好每个节点的权限信息。3、递归数据,删除不需要展示的节点。2、前端请求对树节点进行筛选。

MinisterOL的博客 900

JavaScript实现扁平数组与树结构的相互转换

在解决扁平数组与树结构之间的转换问题时,关键在于识别父子关系并通过建立索引或映射结构进行层次遍历,以实现数据的转换。

快来一起学习前端知识把!加油,前端人 149

Java树形结构筛选

Java树形筛选算法 提示:使用递归方法,个人在项目中有使用到,有问题希望指出: 使用场景:当我们得到一个树形结构数据时,可能需要在树形结构上对数据进行筛选,例如通过文件夹(文件)名称模糊查询相关的文件夹并展现其父级。 缺点:需要查询出完整的树形结构才能用作筛选,在数据量非常庞大的时候并不适用。 一、话不多说直接上代码块 代码如下: import com.alibaba.fastjson.JSON; import lombok.Data; import java.util.ArrayList; import

cyunwli的博客 4031

基于JavaScript的ztreeFilterDemo:快速实现树形数据的输入搜索功能

ztreeFilterDemo是一款基于zTree组件开发的树形控件搜索与过滤功能的演示程序。该程序不仅展示了如何在复杂的树结构数据中快速检索特定节点,还提供了丰富的过滤机制以满足用户对于搜索结果的精确筛选需求。事件驱动编程是一种编程范式,其中程序的流程是由用户或系统触发的事件来决定的。在事件驱动模型中,程序在等待事件发生时处于被动状态,一旦事件发生,程序会有一个反应,通常称为回调函数或事件处理程序。在Web开发中,事件驱动编程允许开发者以模块化的方式响应用户的交互,如点击、按键、鼠标移动等。

weixin_42103128的博客 331

java-根据过滤条件显示树形结构

java根据过滤条件显示树形结构,其中包括所需要的jar包

list转Tree和手动过滤TreeNode

【代码】list转Tree和手动过滤TreeNode。

陆仁丶的博客 670

zedboard(5)spi轮询和中断

一个SPI可以有几个从设备 在程序中使用 s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel) 选择。其实就是吧对应设备的ss拉低。 备注:只选一个ss,可以不用指定。(感觉,还没测试) 这是xspips.c中定义的函数,发送和接收有 XSpiPs_Transfer 和 XSpiPs_PolledTransfer 两个函数,分别采用中断和轮询模式。    一、轮询模式 米联客参考代码,SpiPs_Init中部分和官方例程流程一样,Spi

Kiss丶小坏 5890

js用递归遍历多维数组_JavaScript树结构操作:查找、遍历、筛选、树结构和列表结构相互转换...

经常有同学问树结构的相关操作,也写了很多次,在这里总结一下JS树形结构一些操作的实现思路,并给出了简洁易懂的代码实现。本文内容结构大概如下:一、遍历树结构1. 树结构介绍JS中树结构一般是类似于这样的结构:let 为了更通用,可以用存储了树根节点的列表表示一个树形结构,每个节点的children属性(如果有)是一颗子树,如果没有children属性或者children长度为0,则表示该节点为叶子节...

weixin_39595271的博客 1418

课设报告-超市收银系统 javaweb(附源代码)

超市收银系统由收银员输入顾客的会员卡卡号(若有卡),所购买的货号。从数据库中取出有关价格信息,在把这些信息返回给收银台,同时把收银台的销售总量和有关种类商品的剩余量以及该持卡顾客的消费情况交数据库存储以供查询。另外,对没有卡的消费不记录该顾客的消费情况扥个人信息,如果一个未持卡顾客一次购买满200元,可围棋发放一张会员卡,以后在该商场购物可享受9折优惠。

m0_71106830的博客 2975

【代码审计】RuoYi定时任务漏洞:从SQL注入到RCE的攻防演变

本文深入剖析了RuoYi框架定时任务模块从早期版本无校验到引入黑白名单机制,再到被组合利用实现RCE的完整漏洞演变过程。文章详细分析了SQL注入与定时任务功能结合导致的远程代码执行漏洞,并总结了代码审计与安全开发的核心要点,为开发者提供了重要的安全参考。

yellow的专栏 699

JS树结构操作:查找、遍历、筛选、树结构和列表结构相互转换

来源 |https://wintc.top/article/20经常有同学问树结构的相关操作,也写了很多次,在这里总结一下JS树形结构一些操作的实现思路,并给出了简洁易懂的代码实现。本...

web前端开发 1637

PCL 法线定向【2025最新版】

几种法线定向方法的PCL代码实现。

点云侠的博客 2806

js list遍历_JS树结构操作:查找、遍历、筛选、树结构和列表结构相互转换

经常有同学问树结构的相关操作,也写了很多次,在这里总结一下JS树形结构一些操作的实现思路,并给出了简洁易懂的代码实现。本文内容结构大概如下:一、遍历树结构1. 树结构介绍JS中树结构一般是类似于这样的结构:let tree = [ { id: '1', title: '节点1', children: [ { id: '1-1', title...

weixin_39579726的博客 892

【数据集】CMIP6气候模式数据下载

简介CMIP6及其气候模式数据下载

WW、forever的博客 9356

【cmd】Win10家庭版找不到 gpedit.msc (组策略)的解决方法

目录 一、创建cmd文件 二、以“管理员身份”运行“gpedit.cmd”文件 三、运行“gpedit.msc”命令查看组策略 一、创建cmd文件 (1)新建一个文件名为“gpedit.txt”的txt文本文档: (2)文本中写入以下内容: @echo off pushd "%~dp0" dir /b C:\Windows\servicing\Packages\Micros...

顾三殇 —— 博客空间(软件测试) 4万+

JS筛选多层树结构数据

当有以下数据需要前端根据name属性筛选,需要同时返回包含name的上下级 const treeData=[ { name:'一年级', id:'one', children:[ { name:'一年1班', id:'one-one', children:[ { name:'小明1', id:'XiaoMing1' }, ...

weixin_46196628的博客 1149

GJB 5000B二级-II实施基础

本文主要描述GJB 5000B二级II实施基础与GJB 5000A的变化情况,以及过程域各条款的实施要点

Abel的博客 2581

js 树结构数据的递归操作

一般用于因后端给的数据字段不够完善,类型不正确,需要前端进行处理树数据。一般用于手动设置vue/react的UI库中的树的展开节点。一般用于前端做树的查询功能。

良_123的专栏 3000

NX二次开发PK获取对象类型

PK_ENTITY_ask_class(),获取对象类型建议用这个函数,比较通用,包含所有对象类型,可以替代UF_MODL_ask_edge_type(),UF_MODL_ask_body_type(),UF_MODL_ask_face_type()等函数。

qq_39541524的博客 827

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

树型数据筛选,过滤,和查找某一个,从树型数据中把所有的子节点取出来

树结构的数据筛选 const filters = (e: any) => { let { value } = e.target; let d = JSON.parse(JSON.stringify(treeDataOld)); let datax = filtersX(value, d); setTreedata(datax); }; const filtersX = (val: any, data: Array<any>) => {

weixin_43933139的博客 3547

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

bootstrap-treeview根据条件过滤相关数据

t对需要数据进行分析 需要过滤的数据是一个数组,该数组中每条数据都是由name$$ID$$parentID$$status$$type,需要实现根据相关状态值进行筛选,筛选完成后,对于没有叶子结点的分类菜单,需要移出,不在树上展示。 name ID parentID status type 该条数据名称 该条数据Id号 该条数据的父ID 数据的状态(共四种) 数据的分类(1表示菜单,0表示叶子结点) 思路分析 经过对数据的分析,可以看出来这些记录组成的数据是一种逻辑上的链表结构,由叶子结

heromps的博客 784

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

js中树结构根据条件查找节点返回节点路径的一些思路

  今天在项目中遇到一个问题,需要根据数据库中记录的树结构节点id获取该记录所在目录节点的路径。   大致想法,首先定义变量保存当前路径,然后递归遍历该树节点,在遍历的过程中将遍历到的节点加入到当前路径中,找到该节点后终止递归,最后返回路径即可。   问题,怎样保存当前判断节点的路径以及未找到节点时对路径的处理方法。   现附上代码: var getPathById = function (id, catalog, callback) { //定义变量保存当前结果路径 var tempp

liudanyang_21的博客 1429

vue根据关键字查找树结构

  话不多说,先看效果 需求描述:需要根据关键字找出对应的父结构,简单讲就是搜索树的叶子节点,然后把对应的那个枝干也展现出来,当然枝干也可以搜索,搜索枝干的话就把搜索到的枝干作为叶子节点,优先级为叶子节点大于中间节点(中间节点和叶子节点都有关键字时,以搜索叶子节点为结果) 数据源 data() { //这里存放数据 return { searchKey:undefined, arr:[], sourceArr: [ { cid: 1, name: "父"

Lalo的博客 3586
上一篇: vscode编辑器快捷键
下一篇: Draggable拖拽+Collapse使用(不一样的手风琴)
fineworkmanship
博客等级 码龄6年 7粉丝 20原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值