Similar splice in C++ like the splice in Javascript? - c++

is there a similar method/function in C++ like the splice in Javascript?
Example from W3School:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2,1,"Lemon","Kiwi");
The result of fruits will be:
Banana,Orange,Lemon,Kiwi,Mango
I wan't to be able to do the same thing in C++. I have created an array of boxes that should dissapear one by one when I click on them. I don't know how to do it, please help.
PS. I'm using the SDL library and Microsoft Visual C++ 2010 Express.

If you're using a vector, you have access to the insert method:
#include <vector>
#include <iostream>
#include <string>
int main()
{
std::vector<std::string> fruits = {"Banana", "Orange", "Apple", "Mango"};
auto pos = fruits.begin() + 2;
fruits.insert(pos, {"Lemon", "Kiwi"});
for (auto fruit : fruits) std::cout << fruit << " ";
}
Output: Banana Orange Lemon Kiwi Apple Mango
Here is a Demo.

In C++11:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template<typename T>
vector<T> splice(vector<T>& v, int start, int howmuch, const vector<T>& ar) {
vector<T> result(begin(v) + start, begin(v) + start + howmuch);
v.erase(begin(v) + start, begin(v) + start + howmuch);
v.insert(begin(v) + start, begin(ar), end(ar));
return result;
}
int main() {
vector<string> fruits = {"Banana", "Orange", "Apple", "Mango"};
auto v = splice(fruits, 2, 1, {"Lemon", "Kiwi"});
cout << "Returned value: " << endl;
for (auto &s: v) {
cout << "\t" << s << endl;
}
cout << endl;
cout << "fruits: " << endl;
for (auto &s: fruits) {
cout << "\t" << s << endl;
}
}
Produces the output:
Returned value:
Apple
fruits:
Banana
Orange
Lemon
Kiwi
Mango
It's a templated version so it should work not only with strings;
Function behaves the same as JS version but you have to pass your vector as the first parameter here.

Related

end_unique algorithm, element disappear

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
using namespace std;
void elimdups(vector<string>& words) {
sort(words.begin(), words.end());
for(auto a : words)
{
cout << a << " ";
}
cout << endl;
auto end_unique = unique(words.begin(), words.end());
for (auto a : words)
{
cout << a << " ";
}
cout << endl;
words.erase(end_unique, words.end());
for (auto a : words)
{
cout << a << " ";
}
cout << endl;
}
int main()
{
vector<string> kim = { "love", "peace", "horrible", "love", "peace", "hi", "hi" };
elimdups(kim);
return 0;
}
--
result:
hi hi horrible love love peace peace
hi horrible love peace love peace
hi horrible love peace
end_unique algorithm do not delete elements.
but on the second cout operation, "hi" disappear.
why "hi" disappear on the second line?
auto end_unique = unique(words.begin(), words.end());
for (auto a : words)
//...
Any items from [end_unique, words.end()) have unspecified values after the call to std::unique. That's why the output in the "erased" range seems strange.
If you want to preserve the "erased" words and keep the relative order, std::stable_partition with the appropriate lambda that checks duplicates could have been done.

Print like a dataframe vector pairs c++

I have a map:
std::map<string , double> params{{a , 1}, {b, 6 }, {c, 7}{d,8} }
I want to print it like a python dataframe:
a b c d
1 6 7 8
Also, I dont want it to run twice.
void join_parameters(std::pair<string , double> param){
std::map<string , double> params;
params.insert(param);
for(const auto& elem : params)
{
double a, b , c,d;
if (elem.first =="a"){
a = elem.second; }
else if (elem.first =="b"){
b = elem.second;}
else if (elem.first =="c"){
c = elem.second; }
else {
d = elem.second;
}
}
std::cout << "d " << "a "<< "b " << "c "<< "\n" << d << a << b << c <<std::endl ;
}
Do you have any suggestion for me?
Your code only works for a map with 4 elements and it assumes that those elements have keys "a" till "d". If that is the case then I would suggest you to use a different data structure, for example
struct params_t {
double a,b,c,d;
};
If you do need the map then you should not make assumptions about number of elements or their keys.
You can use two strings to accumulate the two lines of output in a single loop:
#include <map>
#include <string>
#include <utility>
#include <iostream>
int main() {
std::map<std::string , int> params{{"a" , 1}, {"b", 6 }, {"c", 7},{"d",8} };
std::pair<std::string,std::string> lines;
for (const auto& e : params) {
lines.first += e.first + " ";
lines.second += std::to_string(e.second) + " ";
}
std::cout << lines.first << '\n';
std::cout << lines.second << '\n';
}
Note that I changed the mapped type to int because it looks like you want to store integers. For double you need to adjust the code to get propper formatting.

Implementing custom iterator in struct for custom linked list type

I have a linked list using std::list, that is of custom type "node" (std::list<node>) which is implemented through
struct node {
std::string pname;
int time;
};
I am wondering how I can create an iterator so that I can loop through my linked list to be able to print out the contents of 'pname' and 'time', or if the creation of a custom iterator is not needed to do so, would like to know how that could be done. Thanks!
It's pretty straightforward. Something a bit like this:
#include <iostream>
#include <list>
struct node {
std::string pname;
int time;
};
int main()
{
std::list<node> nodes {
{"test 1", 1},
{"test 2", 2},
};
for(auto& n: nodes) // range-based for
std::cout << n.pname << ": " << n.time << '\n';
// iterator
for(auto iter = std::begin(nodes); iter != std::end(nodes); ++iter)
std::cout << iter->pname << ": " << iter->time << '\n';
}
Output:
test 1: 1
test 2: 2
test 1: 1
test 2: 2

How to save unknown size structure (for later retrieval)

My plan is to store a couple dozen rows with 2 items per row and both items will have a different data type. Not sure if this is the right approach and have heard about using vectors but I can't find any samples that will take in 2 items with different types with many rows (an unknown amount of rows) similar to what I'm trying to do here. The following doesn't compile
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct movies_t {
string title;
int year;
} myRecNo[];
void printmovie (movies_t movie);
int main ()
{
string mystr;
for (int i=0; i < 2; i++)
{
switch (i)
{
case 1:
myRecNo[i].title = "2001 A Space Odyssey";
myRecNo[i].year = 1968;
cout << "Auto entry is:\n ";
printmovie (myRecNo[i]);
break;
case 2:
myRecNo[i].title = "2002 A Space Odyssey";
myRecNo[i].year = 1978;
cout << "Auto entry is:\n ";
printmovie (myRecNo[i]);
break;
}
}
return 0;
}
void printmovie (movies_t movie)
{
cout << movie.title;
cout << " (" << movie.year << ")\n";
}
This is the error I get:
Test1.obj||error LNK2019: unresolved external symbol "struct movies_t * myRecNo" (?myRecNo##3PAUmovies_t##A) referenced in function _main|
There are a couple of bad practices in your code, if you are just asking for a way to modify the program so that it will compile and work, see the following:
Declare struct and create struct variables in your main function.
struct movies_t
{
string title;
int year;
};
then, in your main function, movies_t myRecNo[2];
Arrays start at index 0, not 1. so your switch should be
switch (i)
{
case 0:
myRecNo[i].title = "2001 A Space Odyssey";
myRecNo[i].year = 1968;
cout << "Auto entry is:\n ";
printmovie(myRecNo[i]);
break;
case 1:
myRecNo[i].title = "2002 A Space Odyssey";
myRecNo[i].year = 1978;
cout << "Auto entry is:\n ";
printmovie(myRecNo[i]);
break;
}
// the rest of the code..
After you modify these, your code should work.
However, for a better data structure to save an array of paired values, you can use std::vector<std::pair<string, int>> myReg to save your data.
the following code should be much much better, remember to #include <vector>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
void printmovie(std::vector<std::pair<std::string, int>>);
int main()
{
std::vector<std::pair<std::string, int>> myReg;
myReg.push_back({ "2001 A Space Odyssey", 1968 });
myReg.push_back({ "2002 A Space Odyssey", 1978 }); // <- if your compiler is not using c++11 standard or above, please change this line to myReg.push_back(std::pair<std::string, int>("name of the movie", int)); to use to older version of Initializer
printmovie(myReg);
return 0;
}
void printmovie(std::vector<std::pair<std::string, int>> movie)
{
for (auto itor = movie.begin(); itor != movie.end(); ++itor)
{
//first is the first data in the pair, which is the title
//second is the second data in the pair, which is the year
std::cout << (*itor).first << " (" << (*itor).second << ")\n";
}
}
Thanks everyone & #Zhou.
Zhou's code above might work on a newer version of the compiler but I'm using Code::Blocks IDE with MS Visual C++ 2010 compiler.
Here is the vector method that worked:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
void printmovie(std::vector<std::pair<std::string, int>>);
int main()
{
std::vector<std::pair<std::string, int>> myReg;
myReg.push_back(std::pair<std::string, int>("title of the movie", 1968));
myReg.push_back(std::pair<std::string, int>("title of the movie2", 1978));
//myReg.push_back({ "2001 A Space Odyssey", 1968 });
//myReg.push_back({ "2002 A Space Odyssey", 1978 });
printmovie(myReg);
//or to print a single element (the 2nd row) thanks #zhou
std::cout << myReg[1].first << " " << myReg[1].second << std::endl;
return 0;
}
void printmovie(std::vector<std::pair<std::string, int>> movie)
{
for (auto itor = movie.begin(); itor != movie.end(); ++itor)
{
//first is the first data in the pair, which is the title
//second is the second data in the pair, which is the year
std::cout << (*itor).first << " (" << (*itor).second << ")\n";
}
}

Accessing to all the elements from the single member type from the struct in c++

Lets say I have a following structures in c++
struct Fruit
{
std::string name, description;
}
and
struct Fruit Fruits[]
{
{"orange"," Orange is a hybrid of ancient cultivated origin, possibly between pomelo and mandarin. "},
{"apple", " Apple is the pomaceous fruit of the apple tree, species Malus domestica in the rose family. "},
};
My question is, how can I access to all the elements of the single member type of the one struct in c++, or in this case how can I list all the elements of the member type name from the struct Fruit?
Any help would be appreciated. Thanks in advance.
Perhaps you need a dynamic array of pears:
#include <vector>
#include <string>
#include <utility>
#include <iostream>
std::vector<std::pair<std::string, std::string>> fruits {
{ "Apple", "Yum" },
{ "Tomato", "Yuck" }
};
You can iterate this:
for (auto it = fruits.cbegin(), end = fruits.cend(); it != end; ++it)
{
std::cout << "Fruit: " << it->first << ", Description: " << it->second << "\n";
}
Or use the snazzy new range-for-loop:
for (auto const & p : fruits) { /* ... p.first etc ... */ }
how can I list all the elements of the member type name from the struct Fruit?
#include <iostream>
struct Fruit
{
std::string name, description;
};
struct Fruit Fruits[] =
{
{"orange"," Orange is a hybrid of ancient cultivated origin, possibly between pomelo and mandarin. "},
{"apple", " Apple is the pomaceous fruit of the apple tree, species Malus domestica in the rose family. "},
};
int main () {
for(auto& fruit : Fruits ) {
std::cout << fruit.name << "\n";
}
}