1

For example,

const text = "APPLE ORANGE";
const text_position = [0,4,4,7,9];
const inserted_value = ["yo","wo","go","lo","zo"];

For this example, I would like to create an array like this:

return ["yo","APPL","wo","go","E O","lo","RA","zo","NGE"];

Fianal Result

My code:

I am trying to merge into an array from a given string by an array of string positions. There are one string and two arrays given:

const content = "0123456789TEXT";
const footnote_position  = [0, 1, 2, 2, 6]; // string positions 
const footnote_value = ["ZERO", "ONE", "TWO", "TWO", "SIX"]; // inserted values

But for my code and above given content, footnote_position, and footnote_value, the algorithm must output as follow:

["ZEROR","0","ONE","1","TWO","TWO","2345","SIX","67899TEXT"]

My complete code is:

const content = "0123456789TEXT";
const footnote_position = [0, 1, 2, 2, 6]; // must be sorted
const footnote_value = ["ZERO", "ONE", "TWO", "TWO", "SIX"];

const position_set = [...new Set(footnote_position)]; // must be sorted 1,2,6
const contentArray = [];


let textArray = [];
let prev = -1;
let count = footnote_position.length;


for (let index = 0; index < count + 1; index++) {

  switch (index) {

    case 0: // ok
      var item = footnote_position[index];
      if (item != 0) {
        textArray.push(content.substring(0, item));
      }
      footnote_position.forEach((value, position) => {
        if (value == item) {
          textArray.push(footnote_value[position]);

        }
      })
      prev = item;
      break;
    case length: // ok
      textArray.push(content.substring(prev)); // <Text>
      footnote_position.forEach((value, position) => {
        if (value == item) textArray.push(footnote_value[position]);
      })
      break;
    default: // not ok
      var item = footnote_position[index];
      textArray.push(content.substring(prev, item));
      footnote_position.forEach((value, position) => {
        if (value == item) textArray.push(footnote_value[position]);
      })
      prev = item;
      break;
  }
}

console.log(textArray);

Unfortunately, my output is different as follows:

["ZERO", "0", "ONE", "1", "TWO", "TWO", "", "TWO", "TWO", "2345", "SIX", "6789TEXT"]

What went wrong? Do you have any alternative different algorithm solution for this problem?

Plus, I really have no idea why case length: is working. There is no defined variable length in the code.

2
  • I really don't understand the logic behind this algorithm from the given example. Do you mind explaining it? Commented Aug 12, 2020 at 8:22
  • Yes, I added one example, could you please re-read the question? @msmolcic Commented Aug 12, 2020 at 8:38

2 Answers 2

3

Use forEach, slice and maintain last

Update: Fixing the issue of last element. Great suggestion @mplungjan and Thank you.

const text = "APPLE ORANGE";
const text_position = [0, 4, 4, 7, 9];
const inserted_value = ["yo", "wo", "go", "lo", "zo"];

let last = 0;
const output = [];
text_position.forEach((index, i) => {
  const value = text.slice(last, index);
  if (value) {
    output.push(value);
  }

  output.push(inserted_value[i]);
  last = index;
});
if (last < text.length) output.push(text.slice(last));

console.log(output);

Alternate way using flatMap

const text = "APPLE ORANGE";
const text_position = [0, 4, 4, 7, 9];
const inserted_value = ["yo", "wo", "go", "lo", "zo"];

let last = 0;
const output = text_position.flatMap((index, i) => {
  const output = [];
  last < index && output.push(text.slice(last, index));
  output.push(inserted_value[i]);
  last = index;
  (i === (text_position.length - 1)) && (last < text.length) && output.push(text.slice(last));
  return output;
})

console.log(output);

Sign up to request clarification or add additional context in comments.

5 Comments

Almost there, your result is [ "yo", "APPL", "wo", "go", "E O", "lo", "RA", "zo" ] and expected result is [ "yo", "APPL", "wo", "go", "E O", "lo", "RA", "zo", "NGE" ]
If the NGE is fixed, then this is the more elegant solution. I worked on similar, but had already a working example in place
I agree with @mplungjan
Just add if (last < text.length) output.push(text.slice(last)) before the end
Ah, right I missed that @mplungjan, Nay Sie. Thank you very much. :)
1

I rewrote the code to handle your second example

const mergeIt = (content, posArr, valArr) => {
  const arr = content.split("");
  posArr.sort((a, b) => a - b); // must be sorted
  while (posArr.length) {
    const pos = posArr.pop(); // destructive - you may want to clone
    const val = valArr.pop(); // destructive - you may want to clone
    if (val !== null) arr.splice(pos, 0, `|${val}|`);
  }
  return arr.join("").split("|").filter(w => w)
};

let content = "0123456789TEXT";
let footnote_position = [2, 1, 0, 2, 6];
let footnote_value = ["ZERO", "ONE", "TWO", "TWO", "SIX"];
console.log(mergeIt(content, footnote_position, footnote_value))


const text = "APPLE ORANGE";
const text_position = [0, 4, 4, 7, 9];
const inserted_value = ["yo", "wo", "go", "lo", "zo"];
console.log(mergeIt(text, text_position, inserted_value))

// returns  ["yo","APPL","wo","go","E O","lo","RA","zo","NGE"]

3 Comments

Almost there, I added one example in the question for more clarification. Could you please re-read the post again?
Wow, thank you very much for your time and your help. It works now.
It is not as elegant as the other solution but the other solution needs to add any missing strings to the array

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.