【问题标题】:Sorting an element containing a certain string value to a different position within an typescript array将包含某个字符串值的元素排序到打字稿数组中的不同位置
【发布时间】:2020-09-04 07:33:40
【问题描述】:

对于那些回答并阅读了我之前的问题的人,感激不尽。 这个问题是后续问题。

现在我有以下sn-p

public async personNews(serviceBranch?: string[]): Promise<INews> { const fetchResult: IPersonNewsFetchResultEntry[] = await this._get('api/person/news/', newsSchema, true) as IPersonNewsFetchResultEntry[]; const serviceBranches: string[] =
fetchResult.filter((entry, index, array) => { return array.findIndex(({unitID}) => entry.unitID === unitID) === index; }).map(entry => entry.unitID);

我希望将 serviceBranch 包含在我的过滤器中,以便新创建的数组中的元素将 serviceBranch 参数放在顶部或我选择的位置。 例如,现在我的数组看起来像 [TRY, PLO, OMO, MNY, WER, TQA, MNB]。 serviceBranch 参数将是 WER 所以我希望我的数组是 [TRY, WER, OMO, MNY, etc...] 最重要的部分是将该元素移到前 3 位。

对我来说,实现这一结果的最佳方式是什么。 我一直在寻找排序功能,但我所阅读的内容都没有给我想要的结果。 提前致谢。

【问题讨论】:

    标签: arrays typescript sorting typescript2.0


    【解决方案1】:

    我不知道这是否是“最佳”方式,但一种直接的方式是使用数组的 findIndex() 方法来定位您要移动的项目,然后使用 splice()方法两次以删除并在您关心的位置重新插入元素。这是一个可能的实现:

    function moveToPos<T>(arr: T[], pred: (x: T) => boolean, pos: number) {
        const curPos = arr.findIndex(pred);
        if (curPos < 0) return;
        arr.splice(pos, 0, ...arr.splice(curPos, 1));
    }
    

    所以moveToPos() 接受一个数组、一个用于定位元素的谓词以及一个新的元素位置。让我们在一个字符串数组上尝试一下:

    const a = ["TRY", "PLO", "OMO", "MNY", "WER", "TQA", "MNB"];
    console.log(a.join(",")); // TRY,PLO,OMO,MNY,WER,TQA,MNB 
    moveToPos(a, s => s === "WER", 0); // move WER to first position
    console.log(a.join(",")); // WER,TRY,PLO,OMO,MNY,TQA,MNB 
    moveToPos(a, s => s === "WER", 1); // move WER to second position
    console.log(a.join(",")); // TRY,WER,PLO,OMO,MNY,TQA,MNB 
    moveToPos(a, s => s === "WER", 2); // move WER to third position
    console.log(a.join(",")); // TRY,PLO,WER,OMO,MNY,TQA,MNB 
    

    我觉得不错。但也许您只想交换两个元素而不是移动数组?这也是可能的:

    function moveToPos<T>(arr: T[], pred: (x: T) => boolean, pos: number) {
        pos = Math.max(Math.min(pos, arr.length - 1), 0);
        const curPos = arr.findIndex(pred);
        if (curPos < 0) return;
        [arr[curPos], arr[pos]] = [arr[pos], arr[curPos]]; // destructuring
        // or you could do the less tricky way
        // const tmp = arr[curPos];
        // arr[curPos] = arr[pos];
        // arr[pos] = tmp;
    }
    

    因此产生不同的结果:

    const a = ["TRY", "PLO", "OMO", "MNY", "WER", "TQA", "MNB"];
    console.log(a.join(",")); // TRY,PLO,OMO,MNY,WER,TQA,MNB 
    moveToPos(a, s => s === "WER", 0); // move WER to first position 
    console.log(a.join(",")); // WER,PLO,OMO,MNY,TRY,TQA,MNB 
    moveToPos(a, s => s === "WER", 1); // move WER to second position
    console.log(a.join(",")); // PLO,WER,OMO,MNY,TRY,TQA,MNB 
    moveToPos(a, s => s === "WER", 2); // move WER to third position
    console.log(a.join(",")); // PLO,OMO,WER,MNY,TRY,TQA,MNB 
    

    请注意,存在各种边缘情况:如果您的谓词不匹配任何元素怎么办? (然后什么都没有移动;这就是您想要的吗?)如果您的谓词匹配多个元素怎么办? (然后第一个被移动;这就是你想要的吗?)如果你的新位置在数组之外怎么办(那么无论splice() 做什么都会发生什么)数组中的其余元素会发生什么你没有问过(他们以某种方式移动或交换)所以你应该小心并准确地决定你想要什么,这可能会影响实施。

    无论如何,希望对您有所帮助;祝你好运!


    更新:如果您只关心将与谓词匹配的元素移动到列表的前面,同时不理会其余元素,并且您想使用数组的 sort() 方法,您可以执行以下操作:

    function moveToFront<T>(arr: T[], findPred: (x: T) => boolean) {
        arr.sort((x, y) => +findPred(y) - +findPred(x))
    }
    

    您通常需要使用谓词来识别要移动的东西,因为相等运算符仅适用于基元和相同的对象引用。无论如何,这会导致:

    const a = ["TRY", "PLO", "OMO", "MNY", "WER", "TQA", "MNB"];
    console.log(a.join(",")); // TRY,PLO,OMO,MNY,WER,TQA,MNB 
    moveToFront(a, s => s === "WER");
    console.log(a.join(",")); // WER,TRY,PLO,OMO,MNY,TQA,MNB
    

    Playground link to code

    【讨论】:

    • 非常感谢!我会玩弄你给我的东西。
    • 事后看来,是否可以只做一些简单的比较并在排序函数中使用它?例如调用 .sort(pushToFirstPos) private pushToFirstPos(serviceBranch){ //逻辑将 serviceBranch 推到第一个位置。 }
    • 更新了我的答案,但我不知道您使用的是什么平等指标,所以pushToFirstPos() 可能需要采用谓词而不是值。我也不确定你为什么要使用 sort() 而不是 findIndex() 但你去。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2014-09-22
    • 2013-11-03
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    相关资源
    最近更新 更多