0

I am trying to figure out a way to take a string and update values based on a new string that is coming in. The string represents the structure of a table and contains a column name and a column data type.

To do this I am trying to convert the original string and the new string into arrays. Then I need to union the results but update existing columns with their new data types.

For instance, in the below example I want to return 4 columns where col2 is updated from varchar(30 to varchar(20).

var original_schema = 'col1 int,col2 varchar(30),col3 datetime2,col5 bit';
var new_schema = 'col1 int,col2 varchar(20),col3 datetime2,col4 int';

var arr_original_schema = original_schema.replace(/ /g,':').split(",");
var arr_new_schema = new_schema.replace(/ /g,':').split(",");

console.log(arr_original_schema);
console.log(arr_new_schema);

function arrayUnique(array) {
    var a = array.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {           
            //removed
          if(a[i] === a[j])            
                a.splice(j--, 1);
        }
    }

    return a;
}

var uniqueschema = arrayUnique(arr_original_schema.concat(arr_new_schema));
console.log(uniqueschema)

The expected result is: col1 int,col2 varchar(20),col3 datetime2,col4 int,col5 bit"

2
  • Please add example of final expected result Commented Mar 19, 2020 at 20:42
  • Thank you, I added my expected results. Commented Mar 19, 2020 at 21:19

3 Answers 3

1

I'd create objects of it, then use Object.assign

const original_schema = 'col1 int,col2 varchar(30),col3 datetime2,col5 bit';
const new_schema = 'col1 int,col2 varchar(20),col3 datetime2,col4 int';

const objectify = (string) => string.split(',').reduce((a, b) => {
    const [col, type] = b.split(/\s+/);
    a[col] = type;
    return a;
}, {});

const os = objectify(original_schema);
const ns = objectify(new_schema);

const res = Object.entries(Object.assign(os, ns)).map(e => e.join(' ')).join(',');
console.log(res);

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

Comments

1
var original_schema = 'col1 int,col2 varchar(30),col3 datetime2';
var new_schema = 'col1 int,col2 varchar(20),col3 datetime2,col4 int';


const arr_1 = original_schema.split(',');
const arr_0 = (new Array(arr_1.length)).fill(null);
let arr_2 = new_schema.split(',')
arr_2=Object.assign(arr_0, arr_2)

const result =  arr_2.filter(function (el) {
  return el != null;
}).join(',')

console.log(result);

8 Comments

This fails to union the schemas correctly; properties from a that aren't in b aren't carried through.
"For instance, in the below example I want to return 4 columns where col2 is updated from varchar(30 to varchar(20)." he doesn't want union he wants overriding...
I'm talking about properties that aren't in b. In the example, there's an extra column in b, but switch the two around so there's an extra column in a that doesn't exist in b. For example, "a int, b int" and "a float" we should get "a float, b int".
my snippet result is "col1 int,col2 varchar(20),col3 datetime2,col4 int" which is the expected result from the question. isn't it?
Yes, it works on that input but fails on the above case.
|
1

const original_schema = 'col1 int,col2 varchar(30),col3 datetime2,col5 bit';
const new_schema = 'col1 int,col2 varchar(20),col3 datetime2,col4 int';

const originalArr = original_schema.split(",");
const newArr = new_schema.split(",");

// Create single array with duplicates
const mergedArray = [...originalArr, ...newArr];

// Run through merged array with duplicates and create/overwrite existing values
let mergedObj = mergedArray.reduce((acc, item) => {
  let [id, str] = item.split(' ');
  acc[id] = item;
  return acc;
}, {});

// sort the values of object using local compare
// Assume that each value always start with col and number and they should be ordered as such.
// use localCompare to compre these values.
let sorted = Object.values(mergedObj).sort((a, b) => a.localeCompare(b));

console.log(sorted.join(','));

Comments

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.