Related
I have data like this.
var abc =",,,,,,,,,,,,,,,paul,2000,12sc21,logan,123,21sdf34,vfsarwe,456456,32fd23";
abc = abc.split(",");
let stub={};
var results=[];
var key=["name","value","acc"];
var i=0;
var j=0;
for( var i = 0 ; i <abc.length - 1;i++){
stub[key[j]=abc[i];
j++
if(j==3){
results.push(stub);
stub={};
j=0;
}
}
abc = results;
I would like to get those values arranges in form of array of object having those 3 keys:
output should be:
abc = [{"name": "paul", "value": "2000","acc":"12sc21"},{"name":"logan","value":"123","acc":"21sdf34"},{"name":"vfsarwe","value":"456456","acc":"32fd23"}];
but not able to get the desired output. this output only comes when string don't have ,,,,,, in starting. But the data i'm getting is sometimes having ,,,,, in stating.
You can use abc.replace(/(^[,\s]+)/g, '') to remove leading commas or whitespace from the String. Your for loop is also not running for long enough; it is looping until there is only one element left in the Array and then stopping.
Change
for(var i = 0 ; i < abc.length-1; i++)
To
for(var i = 0 ; i < abc.length; i++)
var abc =",,,,,,,,,,,,,,,paul,2000,12sc21,logan,123,21sdf34,vfsarwe,456456,32fd23";
abc = abc.replace(/(^[,\s]+)|([,\s]+$)/g, '').split(",");
let stub={};
var results=[];
var key=["name","value","acc"];
var i=0;
var j=0;
for(var i = 0 ; i < abc.length; i++){
stub[key[j]]=abc[i];
j++
if(j==3){
results.push(stub);
stub={};
j=0;
}
}
abc = results;
console.log(abc);
You can use .replace(/^\,+/, '') to remove all leading commas, then split by comma to get an array, then loop over this array using 3 as step and construct your results:
var abc = ",,,,,,,,,,,,,,,paul,2000,12sc21,logan,123,21sdf34,vfsarwe,456456,32fd23";
var arr = abc.replace(/^\,+/, '').split(",");
var results = [];
for (var i = 0; i < arr.length; i = i + 3) {
results.push({
"name": arr[i],
"value": arr[i + 1],
"acc": arr[i + 2]
});
}
Demo:
var abc = ",,,,,,,,,,,,,,,paul,2000,12sc21,logan,123,21sdf34,vfsarwe,456456,32fd23";
var arr = abc.replace(/^\,+/, '').split(",");
var results = [];
for (var i = 0; i < arr.length; i = i + 3) {
results.push({
"name": arr[i],
"value": arr[i + 1],
"acc": arr[i + 2]
});
}
console.log(results);
You are on the right track with splitting your data on ,. You can then split the data in to chunks of 3, and from there map each chunk to a dict.
var data = ",,,,,,,,,,,,,,,paul,2000,12sc21,logan,123,21sdf34,vfsarwe,456456,32fd23";
var split = data.split(",");
var chunked = [];
while (split.length) {
chunked.push(split.splice(0,3));
}
var res = chunked.map((i) => {
if (!i[0] || !i[1] || !i[2]) {
return null;
}
return {
name: i[0],
value: i[1],
acc: i[2]
};
}).filter((i) => i !== null);
console.log(res);
You can use:
abc.replace(/,+/g, ',').replace(/^,|,$/g, '').split(',');
The regEx replaces removes the data that you are not interested in before performing the split.
or
abc.split(',').filter(Boolean);
The filter(Boolean) will remove the items from the array that could be the equivalent of false once the array has been instantiated.
EDIT:
var abc =",,,,,,,,,,,,,,,paul,2,000,12sc21,logan,123,21sdf34,vfsarwe,456456,32fd23";
var array = abc.replace(/,+/g, ',').replace(/^,|,$/g, '').split(/,([0-9,]+),/);
array = array.filter(Boolean).reduce(function(acc, item) {
if (item.match(/^[0-9,]+$/)) {
acc.push(item);
} else {
acc = acc.concat(item.split(','));
}
return acc;
}, []);
I have 2 strings and I need to construct the below result (could be JSON):
indexLine: "id,first,last,email\n"
dataLine: "555,John,Doe,jd#gmail.com"
Result: "id:555,first:john,....;
What would be the fastest way of joining alternately those 2 strings?
I wrote this - but it seems too straight forward:
function convertToObject(indexLine, dataLine) {
var obj = {};
var result = "";
for (var j = 0; j < dataLine.length; j++) {
obj[indexLine[j]] = dataLine[j]; /// add property to object
}
return JSON.stringify(obj); //-> String format;
}
Thanks.
var indexLine = "id,first,last,email";
var dataLine = "555,John,Doe,jd#gmail.com";
var indexes = indexLine.split(',');
var data = dataLine.split(',');
var result = [];
indexes.forEach(function (index, i) {
result.push(index + ':' + data[i]);
});
console.log(result.join(',')); // Outputs: id:555,first:John,last:Doe,email:jd#gmail.com
If you might have more than one instance of your object to create, you could use this code.
var newarray = [],
thing;
for(var y = 0; y < rows.length; y++){
thing = {};
for(var i = 0; i < columns.length; i++){
thing[columns[i]] = rows[y][i];
}
newarray.push(thing)
}
source
Okay, so I've been working on a sort function for my application, and I've gotten stuck.
Here's my fiddle.
To explain briefly, this code starts with an array of strings, serials, and an empty array, displaySerials:
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"];
var displaySerials = [];
The aim of these functions is to output displaySerials as an array of objects with two properties: beginSerial and endSerial. The way that this is intended to work is that the function loops through the array, and tries to set each compatible string in a range with each other, and then from that range create the object where beginSerial is the lowest serial number in range and endSerial is the highest in range.
To clarify, all serials in a contiguous range will have the same prefix. Once that prefix is established then the strings are broken apart from the prefix and compared and sorted numerically.
So based on that, the desired output from the array serials would be:
displaySerials = [
{ beginSerial: "BHU-008", endSerial: "BHU-011" },
{ beginSerial: "BHU-000", endSerial: "BHU-002" },
{ beginSerial: "TYU-969", endSerial: "TYU-970" }
]
I've got it mostly working on my jsfiddle, the only problem is that the function is pushing one duplicate object into the array, and I'm not sure how it is managing to pass my checks.
Any help would be greatly appreciated.
Marc's solution is correct, but I couldn't help thinking it was too much code. This is doing exactly the same thing, starting with sort(), but then using reduce() for a more elegant look.
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"]
serials.sort()
var first = serials.shift()
var ranges = [{begin: first, end: first}]
serials.reduce(mergeRange, ranges[0])
console.log(ranges) // the expected result
// and this is the reduce callback:
function mergeRange(lastRange, s)
{
var parts = s.split(/-/)
var lastParts = lastRange.end.split(/-/)
if (parts[0] === lastParts[0] && parts[1]-1 === +lastParts[1]) {
lastRange.end = s
return lastRange
} else {
var newRange = {begin: s, end: s}
ranges.push(newRange)
return newRange
}
}
I've got a feeling that it's possible to do it without sorting, by recursively merging the results obtained over small pieces of the array (compare elements two by two, then merge results two by two, and so on until you have a single result array). The code wouldn't look terribly nice, but it would scale better and could be done in parallel.
Nothing too sophisticated here, but it should do the trick. Note that I'm sorting the array from the get-go so I can reliably iterate over it.
Fiddle is here: http://jsfiddle.net/qyys9vw1/
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"];
var myNewObjectArray = [];
var sortedSerials = serials.sort();
//seed the object
var myObject = {};
var previous = sortedSerials[0];
var previousPrefix = previous.split("-")[0];
var previousValue = previous.split("-")[1];
myObject.beginSerial = previous;
myObject.endSerial = previous;
//iterate watching for breaks in the sequence
for (var i=1; i < sortedSerials.length; i++) {
var current = sortedSerials[i];
console.log(current);
var currentPrefix = current.split("-")[0];
var currentValue = current.split("-")[1];
if (currentPrefix === previousPrefix && parseInt(currentValue) === parseInt(previousValue)+1) {
//sequential value found, so update the endSerial with it
myObject.endSerial = current;
previous = current;
previousPrefix = currentPrefix;
previousValue = currentValue;
} else {
//sequence broken; push the object
console.log(currentPrefix, previousPrefix, parseInt(currentValue), parseInt(previousValue)+1);
myNewObjectArray.push(myObject);
//re-seed a new object
previous = current;
previousPrefix = currentPrefix;
previousValue = currentValue;
myObject = {};
myObject.beginSerial = current;
myObject.endSerial = current;
}
}
myNewObjectArray.push(myObject); //one final push
console.log(myNewObjectArray);
I would use underscore.js for this
var bSerialExists = _.findWhere(displaySerials, { beginSerial: displaySettings.beginSerial });
var eSerialExists = _.findWhere(displaySerials, { endSerial: displaySettings.endSerial });
if (!bSerialExists && !eSerialExists)
displaySerials.push(displaySettings);
I ended up solving my own problem because I was much closer than I thought I was. I included a final sort to get rid of duplicate objects after the initial sort was finished.
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"];
var displaySerials = [];
var mapSerialsForDisplay = function () {
var tempArray = serials;
displaySerials = [];
for (var i = 0; i < tempArray.length; i++) {
// compare current member to all other members for similarity
var currentSerial = tempArray[i];
var range = [currentSerial];
var displaySettings = {
beginSerial: currentSerial,
endSerial: ""
}
for (var j = 0; j < tempArray.length; j++) {
if (i === j) {
continue;
} else {
var stringInCommon = "";
var comparingSerial = tempArray[j];
for (var n = 0; n < currentSerial.length; n++) {
if (currentSerial[n] === comparingSerial[n]) {
stringInCommon += currentSerial[n];
continue;
} else {
var currentRemaining = currentSerial.replace(stringInCommon, "");
var comparingRemaining = comparingSerial.replace(stringInCommon, "");
if (!isNaN(currentRemaining) && !isNaN(comparingRemaining) && stringInCommon !== "") {
range = compareAndAddToRange(comparingSerial, stringInCommon, range);
displaySettings.beginSerial = range[0];
displaySettings.endSerial = range[range.length - 1];
var existsAlready = false;
for (var l = 0; l < displaySerials.length; l++) {
if (displaySerials[l].beginSerial == displaySettings.beginSerial || displaySerials[l].endSerial == displaySettings.endSerial) {
existsAlready = true;
}
}
if (!existsAlready) {
displaySerials.push(displaySettings);
}
}
}
}
}
}
}
for (var i = 0; i < displaySerials.length; i++) {
for (var j = 0; j < displaySerials.length; j++) {
if (i === j) {
continue;
} else {
if (displaySerials[i].beginSerial === displaySerials[j].beginSerial && displaySerials[i].endSerial === displaySerials[j].endSerial) {
displaySerials.splice(j, 1);
}
}
}
}
return displaySerials;
}
var compareAndAddToRange = function (candidate, commonString, arr) {
var tempArray = [];
for (var i = 0; i < arr.length; i++) {
tempArray.push({
value: arr[i],
number: parseInt(arr[i].replace(commonString, ""))
});
}
tempArray.sort(function(a, b) {
return (a.number > b.number) ? 1 : ((b.number > a.number) ? -1 : 0);
});
var newSerial = {
value: candidate,
number: candidate.replace(commonString, "")
}
if (tempArray.indexOf(newSerial) === -1) {
if (tempArray[0].number - newSerial.number === 1) {
tempArray.unshift(newSerial)
} else if (newSerial.number - tempArray[tempArray.length - 1].number === 1) {
tempArray.push(newSerial);
}
}
for (var i = 0; i < tempArray.length; i++) {
arr[i] = tempArray[i].value;
}
arr.sort();
return arr;
}
mapSerialsForDisplay();
console.log(displaySerials);
fiddle to see it work
Here's a function that does this in plain JavaScript.
var serials = ["BHU-009", "BHU-008", "BHU-001", "BHU-010", "BHU-002", "TYU-970", "BHU-011", "TYU-969", "BHU-000"];
function transformSerials(a) {
var result = []; //store array for result
var holder = {}; //create a temporary object
//loop the input array and group by prefix
a.forEach(function(val) {
var parts = val.split('-');
var type = parts[0];
var int = parseInt(parts[1], 10);
if (!holder[type])
holder[type] = { prefix : type, values : [] };
holder[type].values.push({ name : val, value : int });
});
//interate through the temp object and find continuous values
for(var type in holder) {
var last = null;
var groupHolder = {};
//sort the values by integer
var numbers = holder[type].values.sort(function(a,b) {
return parseInt(a.value, 10) > parseInt(b.value, 10);
});
numbers.forEach(function(value, index) {
if (!groupHolder.beginSerial)
groupHolder.beginSerial = value.name;
if (!last || value.value === last + 1) {
last = value.value;
groupHolder.endSerial = value.name;
if (index === numbers.length - 1) {
result.push(groupHolder);
}
}
else {
result.push(groupHolder);
groupHolder = {};
last = null;
}
});
}
return result;
}
console.log(transformSerials(serials));
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
I have two arrays like below
var arr = ["x", "y", "z", "a", "b", "c"];
var tgtArr = [{val:"a"}, {val:"b"}]; It does not need to be as lengthy as Array `arr`
This is what I have tried
var dest = new Array(arr.length);
for(var i = 0; i < arr.length; i++){
for(var k = 0; k < tgtArr.length; k++){
dest[i] = dest[i] || [];
if(tgtArr[k].val == arr[i]){
dest[i] = arr[i];
}
}
}
console.log(dest);
My Expected output is (for above tgtArr value)
[{}, {}, {}, {val:"a"}, {val:"b"}, {}];
if tgtArr is empty Array
[{},{},{},{},{},{}]
Here is the fiddle. Any alternative for this, it seems not a good way to me as I am iterating through the entire array everytime.
Short:
var result = arr.map(function(x) {
return tgtArr.some(function(o) { return o.val == x; }) ? {val:x} : {};
});
This is more efficient:
var set = {};
tgtArr.forEach(function(obj, i) {
set[obj.val] = true;
});
var result = arr.map(function(x) {
return x in set ? {val:x} : {};
});
This is the same as Paul's answer, but with a loop instead of map. It collects the keys first based on the val property, then creates a new array either with empty objects if the key isn't in tgtArr, or copies a reference to the object from tgtArr if it is:
function newArray(arr, tgtArr) {
var keys = {},
i = tgtArr.length,
j = arr.length,
newArr = [];
// Get keys
while (i--) keys[tgtArr[i].val] = tgtArr[i];
// Make new array
while (j--) newArr[j] = arr[j] in keys? keys[arr[j]] : {};
return newArr;
}
It should be efficient as it only traverses each array once.
var dest = new Array(arr.length);
for(var i = 0; i < arr.length; i++){
dest[i] = {}
for(var k = 0; k < tgtArr.length; k++){
if(tgtArr[k].val == arr[i]){
dest[i] = tgtArr[k];
}
}
}
console.log(dest);
I like using map rather than loops for this kind of thing (Fiddle):
var result = arr.map(function(x) {
var match = tgtArr.filter(function(y) {
return y.val == x;
});
if (match.length == 1) return match[0];
else return {};
});
This is a possibly inefficient, in that it traverses tgtArr for every item in arr, so O(n*m). If needed, you could fix that by pre-processing tgtArr and converting it to a hash map (Fiddle). This way you've got an O(n+m) algorithm (traverse each array once):
var tgtMap = {};
tgtArr.forEach(function(x) { tgtMap[x.val] = x; })
var result = arr.map(function(x) {
var match = tgtMap[x];
return match || {};
});
var tmp = {};
for (var i = 0; i < tgtArr.length; i++) {
tmp[tgtArr[i].val] = i;
}
var dest = [];
for (var i = 0; i < arr.length; i++) {
var obj= tmp[arr[i]] === undefined ? {} : tgtArr[tmp[arr[i]]];
dest.push(obj);
}
DEMO
I have the following JSON:
[{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557704","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557705","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557706","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557707","mobile":"400089151"}]
I need to extract all "phoneNumber" using a js function.
I'm testing from using html and my function is not so good:
function getNumbers(strJSON)
{
strJSON = "[{\"errorMessage\":\"success\",\"mobile\":\"400089151\",\"phoneNumber\":\"400557704\",\"returnCode\":\"0\"},{\"errorMessage\":\"success\",\"mobile\":\"400089151\",\"phoneNumber\":\"400557705\",\"returnCode\":\"0\"},{\"errorMessage\":\"success\",\"mobile\":\"400089151\",\"phoneNumber\":\"400557706\",\"returnCode\":\"0\"}]";
var len = strJSON.length;
var begin_index = strJSON.indexOf("returnCode") - 2;
var last_index = len - 1;
var string_toSplit = strJSON.substring(begin_index, last_index);
var string_splitted = string_toSplit.split("{");
var out="";
alert(strJSON);
alert("string_splitted");
alert(string_splitted);
for ( var i = 0; i < string_splitted.length; i++)
{
if (string_splitted[i].charAt(string_splitted[i].length - 1) === ",")
{
string_splitted[i] = string_splitted[i].slice(0, -1);
}
var json = "{" + string_splitted[i];
var obj = JSON.parse(json);
if (i == string_splitted.length)
{
out = out + obj.phoneNumber;
}
else
{
out = out + obj.phoneNumber + ",";
}
}
return out;
}
For modern browsers you can use the .map() method
var j = [{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557704","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557705","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557706","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557707","mobile":"400089151"}];
var phones = j.map(function(item){return item.phoneNumber});
Update
After seeing your code (do not try to manually split/parse the json string.. use the JSON.parse method) you should use
function getNumbers(strJSON)
{
var myJson = JSON.parse( strJSON );
return myJson.map(function( item ){ return item.phoneNumber}).join(',');
}
Update: An even better way:
function getNumbers(strJSON)
{
var obj = JSON.parse(strJSON);
return obj.map(x => x.phoneNumber).join(", ")
}
Original Post:
A straight forward method is to just iterate over every object in the array and take the values out individually.
var info = [{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557704","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557705","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557706","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557707","mobile":"400089151"}];
var phoneNumbers = [];
for (var i = 0; i < info.length; i++)
{
phoneNumbers.push(info[i].phoneNumber);
}
console.log(phoneNumbers);
http://jsfiddle.net/hX69r/
UPDATE:
http://jsfiddle.net/hX69r/1/
var info = [{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557704","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557705","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557706","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557707","mobile":"400089151"}];
var infoString = JSON.stringify(info); //this just turns the object array 'info' into a string
var numbers = getNumbers(infoString);
console.log(numbers);
function getNumbers(strJSON)
{
var obj = JSON.parse(strJSON);
var phoneNumbers = [];
for (var i = 0; i < obj.length; i++)
{
phoneNumbers.push(obj[i].phoneNumber);
}
return phoneNumbers.join(", ");
}
Additional Update:
var info = [{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557704","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557705","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557706","mobile":"400089151"},
{"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557707","mobile":"400089151"}];
var infoSingle = {"returnCode":"0","errorMessage":"success","Code":{},"phoneNumber":"400557704","mobile":"400089151"};
console.log(info.length); // prints 4; so you know it has the []
console.log(infoSingle.length); // prints undefined; so you know it doesn't have []
Do not try to re-invent the wheel.
There are many ways to parse JSON already:
Use JSON.parse.
Use jQuery.parseJSON