AS3 about Array.splice()

本文详细介绍了ActionScript 3中splice方法的使用方法,包括如何通过splice方法在数组中添加和删除元素,以及一些注意事项。文章还提供了示例代码帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在实现“从数组中删除一个元素”时,发现splice真是一个特别方便实用的好方法,可实现对数组

下摘自Adobe文档:

AS3 function splice(startIndex:int, deleteCount:uint, ... values):Array

给数组添加元素以及从数组中删除元素。此方法会修改数组但不制作副本。

注意:要在 Array 的子类中覆盖此方法,请使用 ...args 作为参数,如本例所示:

public override function splice(...args) {    // your statements here  } 

参数 startIndex:int — 一个整数,它指定数组中开始进行插入或删除的位置处的元素的索引。您可以用一个负整数来指定相对于数组结尾的位置(例如,-1 是数组的最后一个元素)。
deleteCount:uint — 一个整数,它指定要删除的元素数量。该数量包括 startIndex 参数中指定的元素。如果没有为 deleteCount 参数指定值,则该方法将删除从 startIndex 元素到数组中最后一个元素的所有值。如果该参数的值为 0,则不删除任何元素。
...values — 用逗号分隔的一个或多个值的可选列表或数组,此列表或数组将插入到此数组中由 startIndex 参数指定的位置。

返回 Array — 一个数组,包含从原始数组中删除的元素。 示例
下面的代码创建 Array 对象 vegetables,其中包含元素 [spinach, green pepper, cilantro, onion, avocado]。然后,使用参数 2 和 2 调用 splice() 方法,以将 cilantro 和 onion 赋予 spliced 数组。vegetables 数组中就包含 [spinach,green pepper,avocado]。再次调用 splice() 方法(使用参数 1、0 和 spliced 数组),以将 [cilantro,onion] 作为以下数组中的第二个元素:vegetables。 var vegetables:Array = new Array("spinach",                 "green pepper",                 "cilantro",                 "onion",                 "avocado");var spliced:Array = vegetables.splice(2, 2);trace(vegetables); // spinach,green pepper,avocadotrace(spliced);    // cilantro,onionvegetables.splice(1, 0, spliced);trace(vegetables); // spinach,cilantro,onion,green pepper,avocado 请注意,cilantro 和 onion 输出时好像 vegetables 有 5 个元素,但它实际上只有 4 个元素(其中第二个元素是一个包含两个元素的数组)。若要单独添加 cilantro 和 onion,可使用:

var vegetables:Array = new Array("spinach",                 "green pepper",                 "cilantro",                 "onion",                 "avocado");

  var spliced:Array = vegetables.splice(2, 2);

trace(vegetables); // spinach,green pepper,avocado

trace(spliced);         // cilantro,onion

vegetables.splice(1, 0, "cilantro", "onion"); trace(vegetables); // spinach,cilantro,onion,green pepper,avocado                                                                                                                        

与splice()相关的:

as3如何彻底删除数组中的一个对象

移除数组中的某个对象,比方说array数组索引号为i的对象,可以这样实现:

removeChild(array[i]);

array.splice(i, 1);

移除数组中的全部对象,要用循环一个个从显示列表中移除,因为是全部移除,不需要一个个从数组中删除了,最后将数组设为null就行了:

for(var i in array) {       removeChild(array[i]); }

array = null;

 

在数组元素上使用 delete 运算符

delete 运算符用于将数组元素的值设置为 undefined,但它不会从数组中删除元素。例如,下面的代码在 oceans 数组的第三个元素上使用 delete 运算符,但此数组的长度仍然为 5:

var oceans:Array = ["Arctic", "Pacific", "Victoria", "Indian","Atlantic"];

delete oceans[2];

trace(oceans); // 输出:Arctic,Pacific,,Indian,Atlantic

trace(oceans[2]); // 输出:undefined

trace(oceans.length); // 输出:5

 

可以使用数组的 length 属性截断数组

如果将数组的 length 属性设置为小于数组当前长度的值,则会截断数组,在索引号高于 length 的新值减 1 处所存储的任何元素将被删除。

例如,如果 oceans 数组的排序是将所有有效项放在数组的开始处,则可以使用 length 属性删除数组末尾的项,如以下代码所示:

var oceans:Array = ["Arctic", "Pacific", "Victoria", "Aral","Superior"];

oceans.length = 2;

trace(oceans); // 输出:Arctic,Pacific

转载于:https://www.cnblogs.com/regalys168/p/3581389.html

class KeyWordSpotter(torch.nn.Module): def __init__( self, ckpt_path, config_path, token_path, lexicon_path, threshold, min_frames=5, max_frames=250, interval_frames=50, score_beam=3, path_beam=20, gpu=-1, is_jit_model=False, ): super().__init__() os.environ[&#39;CUDA_VISIBLE_DEVICES&#39;] = str(gpu) with open(config_path, &#39;r&#39;) as fin: configs = yaml.load(fin, Loader=yaml.FullLoader) dataset_conf = configs[&#39;dataset_conf&#39;] # feature related self.sample_rate = 16000 self.wave_remained = np.array([]) self.num_mel_bins = dataset_conf[&#39;feature_extraction_conf&#39;][ &#39;num_mel_bins&#39;] self.frame_length = dataset_conf[&#39;feature_extraction_conf&#39;][ &#39;frame_length&#39;] # in ms self.frame_shift = dataset_conf[&#39;feature_extraction_conf&#39;][ &#39;frame_shift&#39;] # in ms self.downsampling = dataset_conf.get(&#39;frame_skip&#39;, 1) self.resolution = self.frame_shift / 1000 # in second # fsmn splice operation self.context_expansion = dataset_conf.get(&#39;context_expansion&#39;, False) self.left_context = 0 self.right_context = 0 if self.context_expansion: self.left_context = dataset_conf[&#39;context_expansion_conf&#39;][&#39;left&#39;] self.right_context = dataset_conf[&#39;context_expansion_conf&#39;][ &#39;right&#39;] self.feature_remained = None self.feats_ctx_offset = 0 # after downsample, offset exist. # model related if is_jit_model: model = torch.jit.load(ckpt_path) # For script model, only cpu is supported. device = torch.device(&#39;cpu&#39;) else: # Init model from configs model = init_model(configs[&#39;model&#39;]) load_checkpoint(model, ckpt_path) use_cuda = gpu >= 0 and torch.cuda.is_available() device = torch.device(&#39;cuda&#39; if use_cuda else &#39;cpu&#39;) self.device = device self.model = model.to(device) self.model.eval() logging.info(f&#39;model {ckpt_path} loaded.&#39;) self.token_table = read_token(token_path) logging.info(f&#39;tokens {token_path} with &#39; f&#39;{len(self.token_table)} units loaded.&#39;) self.lexicon_table = read_lexicon(lexicon_path) logging.info(f&#39;lexicons {lexicon_path} with &#39; f&#39;{len(self.lexicon_table)} units loaded.&#39;) self.in_cache = torch.zeros(0, 0, 0, dtype=torch.float) # decoding and detection related self.score_beam = score_beam self.path_beam = path_beam self.threshold = threshold self.min_frames = min_frames self.max_frames = max_frames self.interval_frames = interval_frames self.cur_hyps = [(tuple(), (1.0, 0.0, []))] self.hit_score = 1.0 self.hit_keyword = None self.activated = False self.total_frames = 0 # frame offset, for absolute time self.last_active_pos = -1 # the last frame of being activated self.result = {} def set_keywords(self, keywords): # 4. parse keywords tokens assert keywords is not None, \ &#39;at least one keyword is needed, &#39; \ &#39;multiple keywords should be splitted with comma(,)&#39; keywords_str = keywords keywords_list = keywords_str.strip().replace(&#39; &#39;, &#39;&#39;).split(&#39;,&#39;) keywords_token = {} keywords_idxset = {0} keywords_strset = {&#39;<blk>&#39;} keywords_tokenmap = {&#39;<blk>&#39;: 0} for keyword in keywords_list: strs, indexes = query_token_set(keyword, self.token_table, self.lexicon_table) keywords_token[keyword] = {} keywords_token[keyword][&#39;token_id&#39;] = indexes keywords_token[keyword][&#39;token_str&#39;] = &#39;&#39;.join(&#39;%s &#39; % str(i) for i in indexes) [keywords_strset.add(i) for i in strs] [keywords_idxset.add(i) for i in indexes] for txt, idx in zip(strs, indexes): if keywords_tokenmap.get(txt, None) is None: keywords_tokenmap[txt] = idx token_print = &#39;&#39; for txt, idx in keywords_tokenmap.items(): token_print += f&#39;{txt}({idx}) &#39; logging.info(f&#39;Token set is: {token_print}&#39;) self.keywords_idxset = keywords_idxset self.keywords_token = keywords_token def accept_wave(self, wave): assert isinstance(wave, bytes), \ "please make sure the input format is bytes(raw PCM)" # convert bytes into float32 data = [] for i in range(0, len(wave), 2): value = struct.unpack(&#39;<h&#39;, wave[i:i + 2])[0] data.append(value) # here we don&#39;t divide 32768.0, # because kaldi.fbank accept original input wave = np.array(data) wave = np.append(self.wave_remained, wave) if wave.size < (self.frame_length * self.sample_rate / 1000) \ * self.right_context : self.wave_remained = wave return None wave_tensor = torch.from_numpy(wave).float().to(self.device) wave_tensor = wave_tensor.unsqueeze(0) # add a channel dimension feats = kaldi.fbank(wave_tensor, num_mel_bins=self.num_mel_bins, frame_length=self.frame_length, frame_shift=self.frame_shift, dither=0, energy_floor=0.0, sample_frequency=self.sample_rate) # update wave remained feat_len = len(feats) frame_shift = int(self.frame_shift / 1000 * self.sample_rate) self.wave_remained = wave[feat_len * frame_shift:] if self.context_expansion: assert feat_len > self.right_context, \ "make sure each chunk feat length is large than right context." # pad feats with remained feature from last chunk if self.feature_remained is None: # first chunk # pad first frame at the beginning, # replicate just support last dimension, so we do transpose. feats_pad = F.pad(feats.T, (self.left_context, 0), mode=&#39;replicate&#39;).T else: feats_pad = torch.cat((self.feature_remained, feats)) ctx_frm = feats_pad.shape[0] - (self.right_context + self.right_context) ctx_win = (self.left_context + self.right_context + 1) ctx_dim = feats.shape[1] * ctx_win feats_ctx = torch.zeros(ctx_frm, ctx_dim, dtype=torch.float32) for i in range(ctx_frm): feats_ctx[i] = torch.cat(tuple( feats_pad[i:i + ctx_win])).unsqueeze(0) # update feature remained, and feats self.feature_remained = \ feats[-(self.left_context + self.right_context):] feats = feats_ctx.to(self.device) if self.downsampling > 1: last_remainder = 0 if self.feats_ctx_offset == 0 \ else self.downsampling - self.feats_ctx_offset remainder = (feats.size(0) + last_remainder) % self.downsampling feats = feats[self.feats_ctx_offset::self.downsampling, :] self.feats_ctx_offset = remainder \ if remainder == 0 else self.downsampling - remainder return feats def decode_keywords(self, t, probs): absolute_time = t + self.total_frames # search next_hyps depend on current probs and hyps. next_hyps = ctc_prefix_beam_search(absolute_time, probs, self.cur_hyps, self.keywords_idxset, self.score_beam) # update cur_hyps. note: the hyps is sort by path score(pnb+pb), # not the keywords&#39; probabilities. cur_hyps = next_hyps[:self.path_beam] self.cur_hyps = cur_hyps def execute_detection(self, t): absolute_time = t + self.total_frames hit_keyword = None start = 0 end = 0 # hyps for detection hyps = [(y[0], y[1][0] + y[1][1], y[1][2]) for y in self.cur_hyps] # detect keywords in decoding paths. for one_hyp in hyps: prefix_ids = one_hyp[0] # path_score = one_hyp[1] prefix_nodes = one_hyp[2] assert len(prefix_ids) == len(prefix_nodes) for word in self.keywords_token.keys(): lab = self.keywords_token[word][&#39;token_id&#39;] offset = is_sublist(prefix_ids, lab) if offset != -1: hit_keyword = word start = prefix_nodes[offset][&#39;frame&#39;] end = prefix_nodes[offset + len(lab) - 1][&#39;frame&#39;] for idx in range(offset, offset + len(lab)): self.hit_score *= prefix_nodes[idx][&#39;prob&#39;] break if hit_keyword is not None: self.hit_score = math.sqrt(self.hit_score) break duration = end - start if hit_keyword is not None: if self.hit_score >= self.threshold and \ self.min_frames <= duration <= self.max_frames \ and (self.last_active_pos == -1 or end - self.last_active_pos >= self.interval_frames): self.activated = True self.last_active_pos = end logging.info( f"Frame {absolute_time} detect {hit_keyword} " f"from {start} to {end} frame. " f"duration {duration}, score {self.hit_score}, Activated.") elif self.last_active_pos > 0 and \ end - self.last_active_pos < self.interval_frames: logging.info( f"Frame {absolute_time} detect {hit_keyword} " f"from {start} to {end} frame. " f"but interval {end-self.last_active_pos} " f"is lower than {self.interval_frames}, Deactivated. ") elif self.hit_score < self.threshold: logging.info(f"Frame {absolute_time} detect {hit_keyword} " f"from {start} to {end} frame. " f"but {self.hit_score} " f"is lower than {self.threshold}, Deactivated. ") elif self.min_frames > duration or duration > self.max_frames: logging.info( f"Frame {absolute_time} detect {hit_keyword} " f"from {start} to {end} frame. " f"but {duration} beyond range" f"({self.min_frames}~{self.max_frames}), Deactivated. ") self.result = { "state": 1 if self.activated else 0, "keyword": hit_keyword if self.activated else None, "start": start * self.resolution if self.activated else None, "end": end * self.resolution if self.activated else None, "score": self.hit_score if self.activated else None } def forward(self, wave_chunk): feature = self.accept_wave(wave_chunk) if feature is None or feature.size(0) < 1: return {} # # the feature is not enough to get result. feature = feature.unsqueeze(0) # add a batch dimension logits, self.in_cache = self.model(feature, self.in_cache) probs = logits.softmax(2) # (batch_size, maxlen, vocab_size) probs = probs[0].cpu() # remove batch dimension for (t, prob) in enumerate(probs): t *= self.downsampling self.decode_keywords(t, prob) self.execute_detection(t) if self.activated: self.reset() # since a chunk include about 30 frames, # once activated, we can jump the latter frames. # TODO: there should give another method to update result, # avoiding self.result being cleared. break # update frame offset self.total_frames += len(probs) * self.downsampling # For streaming kws, the cur_hyps should be reset if the time of # a possible keyword last over the max_frames value you set. # see this issue:https://github.com/duj12/kws_demo/issues/2 if len(self.cur_hyps) > 0 and len(self.cur_hyps[0][0]) > 0: keyword_may_start = int(self.cur_hyps[0][1][2][0][&#39;frame&#39;]) if (self.total_frames - keyword_may_start) > self.max_frames: self.reset() return self.result def reset(self): self.cur_hyps = [(tuple(), (1.0, 0.0, []))] self.activated = False self.hit_score = 1.0 def reset_all(self): self.reset() self.wave_remained = np.array([]) self.feature_remained = None self.feats_ctx_offset = 0 # after downsample, offset exist. self.in_cache = torch.zeros(0, 0, 0, dtype=torch.float) self.total_frames = 0 # frame offset, for absolute time self.last_active_pos = -1 # the last frame of being activated self.result = {}请帮我缕清整个脉络
最新发布
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值